xml - Limit the result when using following:: in XSL select -
i have complex xml input, need transform flat structure, denormelize tree in xml document repeating related nodes.
source xml lookes this:
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="forom%20sample.xsl"?> <customers> <customer> <id>1</id> <name>john madsen</name> <accounts> <account> <id>111</id> <name>aaa</name> <value>11234</value> </account> <account> <id>222</id> <name>bbb</name> <value>64</value> </account> </accounts> <profile> <gender>m</gender> <age>32</age> </profile> </customer> <customer> <id>2</id> <name>dona m. graduate</name> <accounts> <account> <id>333</id> <name>ccc</name> <value>5215</value> </account> <account> <id>555</id> <name>fff</name> <value>6325</value> </account> </accounts> <profile> <gender>f</gender> <age>36</age> </profile> </customer> </customers>
desired flat structure should this:
<?xml version="1.0" encoding="utf-8"?> <accounts> <account> <customerid>1</customerid> <customername>john madsen</customername> <id>111</id> <name>aaa</name> <value>11234</value> <gender>m</gender> <age>32</age> </account> <account> <customerid>1</customerid> <customername>john madsen</customername> <id>222</id> <name>bbb</name> <value>64</value> <gender>m</gender> <age>32</age> </account> <account> <customerid>2</customerid> <customername>dona m. graduate</customername> <id>333</id> <name>ccc</name> <value>5215</value> <gender>f</gender> <age>36</age> </account> <account> <customerid>2</customerid> <customername>dona m. graduate</customername> <id>555</id> <name>fff</name> <value>6325</value> <gender>f</gender> <age>36</age> </account>
i using following xsl code:
<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:template match="/"> <accounts> <xsl:for-each select="customers/customer/accounts/account"> <account> <xsl:apply-templates select="ancestor::customer/*[not(*)]"/> <xsl:copy-of select="*" /> <xsl:copy-of select="following::profile/*"/> </account> </xsl:for-each> </accounts> </xsl:template> <xsl:template match="customer/*[not(*)]"> <xsl:element name="{concat('customer', name())}"> <xsl:copy-of select="@*|node()"/> </xsl:element> </xsl:template>
however, result this:
<?xml version="1.0" encoding="utf-8"?> <accounts> <account> <customerid>1</customerid> <customername>john madsen</customername> <id>111</id> <name>aaa</name> <value>11234</value> <gender>m</gender> <age>32</age> <gender>f</gender> <age>36</age> </account> <account> <customerid>1</customerid> <customername>john madsen</customername> <id>222</id> <name>bbb</name> <value>64</value> <gender>m</gender> <age>32</age> <gender>f</gender> <age>36</age> </account> <account> <customerid>2</customerid> <customername>dona m. graduate</customername> <id>333</id> <name>ccc</name> <value>5215</value> <gender>f</gender> <age>36</age> </account> <account> <customerid>2</customerid> <customername>dona m. graduate</customername> <id>555</id> <name>fff</name> <value>6325</value> <gender>f</gender> <age>36</age> </account>
note first node have 2 gender , 2 age nodes, happens keyword following:: not limiting self following nodes within current customer node, rather takes follwing nodes in entire document.
so question is, how can limit following:: keyword? or there way copy profile child nodes each account node?
thanks rafi asraf
you can use following-sibling::profile
on parent accounts
element instead of overly broad -for particular case- selector following::profile
:
<xsl:copy-of select="../following-sibling::profile/*"/>
Comments
Post a Comment