-1

I posted this question here. It was answered and I'm happy with it. It's just here to reference the XML input and output.

XML to XML XSLT transformation. MSXML in VBScript

Here is my stylesheet:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="urn:myNameSpace" exclude-result-prefixes="b">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/b:MYImportFile">

<MYImportFile>

    <xsl:for-each select="b:SAMPLE">

    <SAMPLE>

        <SAMPLEID>
        <xsl:value-of select="b:SAMPLEID"/>
        </SAMPLEID>

        <NAME1_1>
        <xsl:value-of select="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[1]/b:DATAVALUE"/>
        </NAME1_1>

        <xsl:choose> 
            <xsl:when test="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[2]/b:DATAVALUE">
                <NAME1_2>
                <xsl:value-of select="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[2]/b:DATAVALUE"/>
                </NAME1_2>
            </xsl:when>
            <xsl:otherwise>
                <NAME1_2>
                <xsl:value-of select="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[1]/b:DATAVALUE"/>
                </NAME1_2>
            </xsl:otherwise>
        </xsl:choose>


        '''''''''''''''''''there are 100 NAME entires to recieve the 100 locations

    </SAMPLE>

    </xsl:for-each>

</MYImportFile>

</xsl:template>
</xsl:stylesheet>

What change do I need to make to this to make that </xsl:for-each> to a <xsl:apply-templates>? Is it an easy change? Or is this going to take an overhaul of the entire stylesheet?

Dan
  • 758
  • 6
  • 20

1 Answers1

1

If there a repetitions of the same code, it might be possible to implement them in a template so an overhaul is helpful anyway:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:b="urn:ohLookHEREaNamespacedeclaration"
    exclude-result-prefixes="b"
    version="1.0">

  <xsl:strip-space elements="*"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
     <xsl:element name="{local-name()}">
        <xsl:apply-templates select="b:SAMPLE"/>
     </xsl:element>
  </xsl:template>

  <xsl:template match="b:SAMPLE">
      <xsl:element name="{local-name()}">
          <xsl:apply-templates select="b:SAMPLEID | b:LOCATION"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="*">
      <xsl:element name="{local-name()}">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="b:LOCATION">
      <xsl:element name="{b:LOCATIONNAME}_1">
          <xsl:value-of select="b:DATA[1]/b:DATAVALUE"/>
      </xsl:element>
      <xsl:element name="{b:LOCATIONNAME}_2">
          <xsl:value-of select="b:DATA[2]/b:DATAVALUE | b:DATA[1][current()[not(b:DATA[2])]]/b:DATAVALUE"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFWRAp3

But in general, instead of doing <xsl:for-each select="foo"><bar>...</bar></xsl:for-each> you can of course use <xsl:apply-templates select="foo"/> with a matching <xsl:template match="foo"><bar>...</bar></xsl:template>, if that is what your main question is about.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • This is actually FANTASTIC. If I could upvote it three times I would. It's short, it's sweet, it's elegant and I understand exactly what it is doing. Let's say I wanted to pick only certain `"{b:LOCATIONNAME}_x"` instead of all 100? Is there a way to do this without creating a separate template for each one that I want? I might have to do a conditional inside a for-each here instead of a template maybe? – Dan Jan 31 '20 at 20:10
  • 1
    The apply-templates `` selects all `b:LOCATION` elements inside each `b:SAMPLE`, you can add a predicate there e.g. `` or ``. Another option would be to add an empty template with a condition of the elements you don't want to be output e.g. ``. You might want to ask a new question detaling the "pick only certain". – Martin Honnen Jan 31 '20 at 21:55
  • I really have to learn more xslt. I have to say again, that’s a beautiful bit of code. I needed to experiment a little to figure out what it all means but I think I’ve got a handle on it and it really is superb. I appreciate it. I’ll see if I can adjust with the additional information you’ve given me here. – Dan Jan 31 '20 at 23:22