V.Plotnikov
V.Plotnikov

Reputation: 53

XSLT comma separation for sublist of list (complex case)

real xml structure

<GTD>
<BLOCK>
  <G44>
    <G4403>1</G4403>
    <G441>02001</G441>
    <G442>N/A</G442>
    <G443>2015-04-12</G443>
  </G44>
  <G44>
    <G4403>1</G4403>
    <G441>02015</G441>
    <G442>143561</G442>
    <G443>2015-07-28</G443>
  </G44>
  <G44>
    <G4403>1</G4403>
    <G441>03011</G441>
    <G442>SRSC-3399709-2015</G442>
    <G443>2014-12-01</G443>
  </G44>
  <G44>
    <G4403>1</G4403>
    <G441>02015</G441>
    <G442>143537</G442>
    <G443>2015-07-26</G443>
  </G44>
  <G44>
    <G4403>1</G4403>
    <G441>03012</G441>
    <G442>1</G442>
    <G443>2014-12-01</G443>
  </G44>
</BLOCK>
<BLOCK>
  ...
</BLOCK>
</GTD>

in result XML i must have from each G44 with G441 = 02015 concatinated string with commas delimiter

<GTD>
<LINE>
  <DOCNUMBER>
    143561, 143537
  </DOCNUMBER>
</LINE>
</GTD>

The question connected with another one (XSLT comma separation for sublist of list)

Upvotes: 1

Views: 80

Answers (1)

Abel
Abel

Reputation: 57159

Not sure why you tagged this "complex case" ;). Here's how to do this with XSLT:

<xsl:template match="/">
    <GTD><LINE><DOCNUMBER>
    <xsl:apply-templates select="GTD/BLOCK/G44[G441 = '02015']" />
    </DOCNUMBER></LINE></GTD>
</xsl:template>

<xsl:template match="G44">
    <xsl:value-of select="G442" />
    <xsl:if test="position() != last()">
        <xsl:text>, </xsl:text>
    </xsl:if>
</xsl:template>

This results in:

<GTD>
  <LINE>
    <DOCNUMBER>143561, 143537</DOCNUMBER>
  </LINE>
</GTD>

Update, adding suggestion from comment

To give a hint as to how to expand this based on your comment on PACKNUMBER:

<xsl:template match="/">
    <GTD><LINE>
        <DOCNUMBER>
            <xsl:apply-templates select="GTD/BLOCK/G44[G441 = '02015']" />
        </DOCNUMBER>
        <PACKNUMBER>
            <xsl:apply-templates select="GTD/BLOCK/G44[G441 = '02001']" />
        </PACKNUMBER>
    </LINE></GTD>
</xsl:template>

<xsl:template match="G44[G441 = '02015']">
    <xsl:value-of select="G442" />
    <xsl:if test="position() != last()">
        <xsl:text>, </xsl:text>
    </xsl:if>
</xsl:template>

<xsl:template match="G44[G441 = '02001']">
    <xsl:value-of select="G441" />
    <xsl:text>, </xsl:text>
    <xsl:value-of select="G443" />
    <xsl:if test="position() != last()">
        <xsl:text>, </xsl:text>
    </xsl:if>
</xsl:template>

You can decide whether you want to repeat the predicate, or switch modes. But essentially, the way to do this is:

  • add a new collection by adding a new apply-templates
  • describe what you want with it by adding a new matching template

In case of overlap (same output to generate for another collection), you can add multiple matches in one by using match="G44[G441 = '02015' or G441 = 'xyz]">.

Upvotes: 1

Related Questions