0

Input XML structure:

<Customer>
   <Order>
      <item>
        <name>ID</name>
        <value>11111</value>
      </item>
   </Order>
   <Order>
      <item>
        <name>ID</name>
        <value>11111</value>
      </item>
   </Order>
    <Order>
      <item>
        <name>ID</name>
        <value>22222</value>
      </item>
   </Order>
   <Order>
      <item>
        <name>ID</name>
        <value>33333</value>
      </item>
   </Order>
</Customer>

Output should be :

<Customer>
   <Order>
      <item>
        <name>ID</name>
        <value>11111</value>
      <item>
   </Order>
   <Order>
      <item>
        <name>ID</name>
        <value>11111</value>
      </item>
   </Order>
</Customer>
<Customer>
    <Order>
      <item>
        <name>ID</name>
        <value>22222</value>
      </item>
   </Order>
</Customer>
<Customer>
    <Order>
      <item>
        <name>ID</name>
        <value>33333</value>
      </item>
   </Order>
</Customer>

Here the /Customer/<Order/item/value will come dynamically. Please anyone give a solution for this transformation.

2
  • You do realize that the requested output is invalid XML (you need a single document element)? Is there an element that is supposed to wrap that content(e.g. <doc><Customer>...</Customer><Customer>...</Customer></doc>)? Commented Mar 15, 2011 at 11:13
  • @Mads Hansen: About output validation, do note that for xml serialization method there are two options, from w3.org/TR/xslt#section-XML-Output-Method: "The xml output method outputs the result tree as a well-formed XML external general parsed entity. If the root node of the result tree has a single element node child and no text node children, then the entity should also be a well-formed XML document entity." Commented Mar 16, 2011 at 0:42

1 Answer 1

1

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kOrderByValue" match="Order" use="item/value"/>
    <xsl:template match="Customer">
        <xsl:for-each select="Order[count(.|key('kOrderByValue',
                                                item/value
                                            )[1]
                                    ) = 1]">
            <Customer>
                <xsl:apply-templates select="key('kOrderByValue',
                                                 item/value
                                             )"/>
            </Customer>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Output:

<Customer>
    <Order>
        <item>
            <name>ID</name>
            <value>11111</value>
        </item>
    </Order>
    <Order>
        <item>
            <name>ID</name>
            <value>11111</value>
        </item>
    </Order>
</Customer>
<Customer>
    <Order>
        <item>
            <name>ID</name>
            <value>22222</value>
        </item>
    </Order>
</Customer>
<Customer>
    <Order>
        <item>
            <name>ID</name>
            <value>33333</value>
        </item>
    </Order>
</Customer>

Note: grouping Customer's Order children by value.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 Good solution. I hadn't noticed the grouping of orders when I posted mine. Deleting my answer.
@Mads Hansen: Thanks. Reposting comment above because I think it has some value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.