I'm a bit new to XSLT and I'm trying to group up the child elements that are having similar ids. Really appreciate your help.
For example, my data structure looks something like this:
<root>
<Persons xmlns:p="http://test1.com" xmlns:pid="http://test1.com/person">
<Person>
<Data xmlns="http://test1.com/person">
<personId>12345</personId>
<dsId>DS_1</dsId>
<data>data1</data>
<ts>2014-09-22</ts>
</Data>
<Data xmlns="http://test1.com/person">
<personId>12345</personId>
<dsId>DS_2</dsId>
<data>data2</data>
<ts>2014-09-22</ts>
</Data>
<Data xmlns="http://test1.com/person">
<personId>12345</personId>
<dsId>DS_3</dsId>
<data>data3</data>
<ts>2014-09-22</ts>
</Data>
<Data xmlns="http://test1.com/person">
<personId>12345</personId>
<dsId>DS_3</dsId>
<data>data4</data>
<ts>2014-09-23</ts>
</Data>
<details xmlns="http://test1.com">
<personId>12345</personId>
</details>
</Person>
</Persons>
</root>
I want to group <Data> items from their <dsId> value and transform above xml into the below structure.
<personData xmlns="http://ift.tt/XWxphV" xmlns:p="http://test1.com" xmlns:pid="http://test1.com/person">
<matchedResults>
<person>
<details>
<personID xmlns="http://test1.com/person">12345</personID>
</details>
<dataSourceResults>
<ds id="DS_1" name="DS_1">
<result loadedTimestamp="2014-09-22">
<entry>data1</entry>
</result>
</ds>
<ds id="DS_2" name="DS_2">
<result loadedTimestamp="2014-09-22">
<entry>data2</entry>
</result>
</ds>
<ds id="DS_3" name="DS_3">
<result loadedTimestamp="2014-09-22">
<entry>data3</entry>
</result>
<result loadedTimestamp="2014-09-23">
<entry>data4</entry>
</result>
</ds>
</dataSourceResults>
</person>
</matchedResults>
</personData>
Please note in above output message <ds id="DS_3".. element contains two <result.. node elements.
Here is the closest transform I could come up with(which doesn't do the grouping).
<xsl:stylesheet version="1.0" xmlns:xsl="http://ift.tt/tCZ8VR" xmlns:p="http://test1.com" xmlns:pid="http://test1.com/person">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<personData xmlns="http://ift.tt/XWxphV">
<matchedResults>
<xsl:for-each select="/root/Persons/Person">
<person>
<details>
<personID xmlns="http://test1.com/person"><xsl:value-of select="p:details/p:personId/text()"/></personID>
</details>
<dataSourceResults>
<xsl:for-each select="pid:Data">
<xsl:variable name="dsId" select="translate(pid:dsId/text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:if test="not($dsId = '')">
<xsl:element name="ds">
<xsl:attribute name="id"><xsl:value-of select="pid:dsId/text()"/></xsl:attribute>
<xsl:attribute name="name"><xsl:value-of select="pid:dsId/text()"/></xsl:attribute>
<xsl:element name="result">
<xsl:attribute name="loadedTimestamp"><xsl:value-of select="pid:ts"/></xsl:attribute>
<entry><xsl:value-of select="pid:data"/></entry>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:for-each>
</dataSourceResults>
</person>
</xsl:for-each>
</matchedResults>
</personData>
</xsl:template>
</xsl:stylesheet>
It only gives me below output.
<personData xmlns="http://ift.tt/XWxphV" xmlns:p="http://test1.com" xmlns:pid="http://test1.com/person">
<matchedResults>
<person>
<details>
<personID xmlns="http://test1.com/person">12345</personID>
</details>
<dataSourceResults>
<ds id="DS_1" name="DS_1">
<result loadedTimestamp="2014-09-22">
<entry>data1</entry>
</result>
</ds>
<ds id="DS_2" name="DS_2">
<result loadedTimestamp="2014-09-22">
<entry>data2</entry>
</result>
</ds>
<ds id="DS_3" name="DS_3">
<result loadedTimestamp="2014-09-22">
<entry>data3</entry>
</result>
</ds>
<ds id="DS_3" name="DS_3">
<result loadedTimestamp="2014-09-23">
<entry>data4</entry>
</result>
</ds>
</dataSourceResults>
</person>
</matchedResults>
</personData>
How can I modify the xsl I have to get the desired transformation?
Thanks in advance...
No comments:
Post a Comment