Search code examples
templatesxsltgroupingxslt-grouping

xslt grouping by calling template


I am new to xslt and trying to learn how to learn grouping using keys and using templates.

Can somebody help me on how can do the following in xslt. I have to call a template from another template to do the transformation.

Thanks

here is my xml.

<Doc>
<ExOrder>121</ExOrder>
<Line>
    <Ordernumber>225</Ordernumber>
    <OrderID>1</OrderID>
    <Quantity>5</Quantity>
</Line>
<Line>
    <Ordernumber>225</Ordernumber>
    <OrderID>5</OrderID>
    <Quantity>5</Quantity>
</Line>
<Line>
    <Ordernumber>226</Ordernumber>
    <OrderID>2</OrderID>
    <Quantity>5</Quantity>
</Line>

And here is how it should look like after.

<Doc>
    <Order>
        <Ordernumber>225</Ordernumber>
        <Line>
            <ID>1</ID>
            <ID>5</ID>
        </Line>
    </Order>
    <Order>
        <Ordernumber>225</Ordernumber>
        <Line>
            <ID>1</ID>
            <ID>5</ID>
        </Line>
    </Order>
</Doc>

Solution

  • I'm going to assume the output you actually want is:

    <Doc>
      <Order>
        <Ordernumber>225</Ordernumber>
        <Line>
          <ID>1</ID>
          <ID>5</ID>
        </Line>
      </Order>
      <Order>
        <Ordernumber>226</Ordernumber>
        <Line>
          <ID>2</ID>
        </Line>
      </Order>
    </Doc>
    

    Since the sample output you provided makes no sense. This XSLT will produce the output above when run on your sample input:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
      <xsl:key name="kOrder" match="Line" use="Ordernumber"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="/*">
        <Doc>
          <xsl:apply-templates select="Line[generate-id() = 
                                            generate-id(key('kOrder', Ordernumber)[1])]" />
        </Doc>
      </xsl:template>
    
      <xsl:template match="Line">
        <Order>
          <xsl:apply-templates select="Ordernumber" />
          <Line>
            <xsl:apply-templates select="key('kOrder', Ordernumber)/OrderID" />
          </Line>
        </Order>
      </xsl:template>
    
      <xsl:template match="OrderID">
        <ID>
          <xsl:value-of select="."/>
        </ID>
      </xsl:template>
    </xsl:stylesheet>