0

I don't have muck knowledge in writing xsl transformations. I have an xml like this

<details>
    <order>
        <id>testID</id>
        <name>testName</name>
    </order>
    <contract>
        <id>1234</id>
        <date>01-01-2015</date>
        <contactAddress>
            <name>ABC</name>
            <email>[email protected]</email>
        </contactAddress>
    </contract>
</details>

I want to transform this xml where each node having child nodes will form an item and will also maintain the relationship using itemID and relatedItemID

Like this

<items>
    <item>
        <name>order</name>
        <itemID>1</itemID>
        <characteristics>
            <characterisctic>
                <name>id</name>
                <value>testID</value>
            </characterisctic>
            <characterisctic>
                <name>name</name>
                <value>testName</value>
            </characterisctic>
        </characteristics>
    </item>
    <item>
        <name>contract</name>
        <itemID>2</itemID>
        <characteristics>
            <characterisctic>
                <name>id</name>
                <value>1234</value>
            </characterisctic>
            <characterisctic>
                <name>date</name>
                <value>01-01-2015</value>
            </characterisctic>
        </characteristics>
    </item>
    <item>
        <name>contactAddress</name>
        <itemID>3</itemID>
        <relatedItemID>2</relatedItemID>
        <characteristics>
            <characterisctic>
                <name>name</name>
                <value>ABC</value>
            </characterisctic>
            <characterisctic>
                <name>email</name>
                <value>[email protected]</value>
            </characterisctic>
        </characteristics>
    </item>
</items>

For this i have written an xsl like this.

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  version="1.0"
  >
    <xsl:variable name="i"></xsl:variable>
    <xsl:template match="/">
        <items>
            <xsl:apply-templates select="//order"/>
            <xsl:apply-templates select="//contract"/>
        </items>
    </xsl:template>
    <xsl:template match="*">
        <item>
            <name><xsl:value-of select="local-name()"/></name>
            <itemID><xsl:value-of select="position()" /></itemID>
            <characteristics>
                <xsl:for-each select="./*">
                    <xsl:choose>
                        <xsl:when test="*">
                            <xsl:apply-templates select="."></xsl:apply-templates>
                        </xsl:when>
                        <xsl:otherwise>
                            <characterisctic>
                                <name> <xsl:value-of select="local-name()"/></name>
                                <value><xsl:value-of select="."/></value>
                            </characterisctic>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </characteristics>
        </item>
    </xsl:template>
</xsl:stylesheet>

But i am not able to figure out how to keep seperate itemID for each item and and maintain the relation using relatedItemID

How to write an xsl for achieving this?

1
  • I think you would want to use the generate-id() function for this. I am not sure I fully understand your purpose here, though: why is order not "related" to details? Commented Oct 24, 2015 at 20:43

1 Answer 1

1

Perhaps a generic solution like this could work for you:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <items>
        <xsl:apply-templates/>
    </items>
</xsl:template>

<xsl:template match="*[*]">
    <item>
        <name>
            <xsl:value-of select="name()"/>
        </name>
        <itemID>
            <xsl:value-of select="generate-id()" />
        </itemID>
        <parentItemID>
            <xsl:value-of select="generate-id(..)" />
        </parentItemID>
        <xsl:variable name="chars" select="*[not(*)]" />
        <xsl:if test="$chars">
            <characteristics>
                <xsl:apply-templates select="$chars" />
            </characteristics>
        </xsl:if>
    </item>
    <xsl:apply-templates select="*[*]" />
</xsl:template>

<xsl:template match="*">
    <characteristic>
        <name>
            <xsl:value-of select="name()"/>
        </name>
        <value>
            <xsl:value-of select="." />
        </value>
    </characteristic>
</xsl:template>

</xsl:stylesheet>

Applied to your example input, the result will be something like (the id values are processor-dependent) this:

<?xml version="1.0" encoding="UTF-8"?>
<items>
   <item>
      <name>details</name>
      <itemID>d0e1</itemID>
      <parentItemID>d0</parentItemID>
   </item>
   <item>
      <name>order</name>
      <itemID>d0e2</itemID>
      <parentItemID>d0e1</parentItemID>
      <characteristics>
         <characteristic>
            <name>id</name>
            <value>testID</value>
         </characteristic>
         <characteristic>
            <name>name</name>
            <value>testName</value>
         </characteristic>
      </characteristics>
   </item>
   <item>
      <name>contract</name>
      <itemID>d0e7</itemID>
      <parentItemID>d0e1</parentItemID>
      <characteristics>
         <characteristic>
            <name>id</name>
            <value>1234</value>
         </characteristic>
         <characteristic>
            <name>date</name>
            <value>01-01-2015</value>
         </characteristic>
      </characteristics>
   </item>
   <item>
      <name>contactAddress</name>
      <itemID>d0e12</itemID>
      <parentItemID>d0e7</parentItemID>
      <characteristics>
         <characteristic>
            <name>name</name>
            <value>ABC</value>
         </characteristic>
         <characteristic>
            <name>email</name>
            <value>[email protected]</value>
         </characteristic>
      </characteristics>
   </item>
</items>
Sign up to request clarification or add additional context in comments.

Comments

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.