xml - How to organize(group) nodes under a closed element - XSLT -
i have tried simple grouping xml xslt 1.0 , worked, here have more complicated , different situation. xml structure this:
<main> <tb> --> elements , stuff - not relevant <city> <area> <position>5</position> <house> --> elements , stuff </house> </area> <area> <position>5</position> <block> --> elements , stuff </block> </area> <area> <position>6</position> <house> --> elements , stuff </house> </area> <area> <position>6</position> <block> --> elements , stuff </block> </area> </city> <city> --> same structure several repetitions of position 7 , 8. </city> </tb> </main> what need group blocks , houses under same position , remove repetition of position numbers. example this:
<city> <area> <position>5</position> <house> --> elements , stuff </house> <block> --> elements , stuff </block> </area> <area> <position>6</position> <house> --> elements , stuff </house> <block> --> elements , stuff </block> </area> </city> <city> --> same structure position 7 , 8. </city> it's harder because position not attribute of area, have identify value of position of area, grab house , block fall under same position, , put them surrounded same <area> </area>.
this looks standard muenchian grouping problem me, grouping area elements (not house or block elements directly) position.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:strip-space elements="*" /> <xsl:output method="xml" indent="yes" /> <xsl:key name="areabyposition" match="area" use="position" /> <xsl:template match="@*|node()"> <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy> </xsl:template> <!-- first area in each position --> <xsl:template match="area[generate-id() = generate-id(key('areabyposition', position)[1])]"> <area> <!-- copy in position element once --> <xsl:apply-templates select="position" /> <!-- copy in sub-elements except position matching areas --> <xsl:apply-templates select=" key('areabyposition', position)/*[not(self::position)]" /> </area> </xsl:template> <!-- ignore other area elements --> <xsl:template match="area" /> </xsl:stylesheet> this assumes there no other elements named area elsewhere in document, if of "some elements , stuff" may named area need bit more specific, example limiting grouping area elements direct children of city:
<xsl:key name="areabyposition" match="city/area" use="position" /> <xsl:template match="city/area[generate-id() = generate-id(key('areabyposition', position)[1])]" priority="2"> ... </xsl:template> <xsl:template match="city/area" priority="1" /> (with explicit priorities because without both templates have same default priority of 0.5)
Comments
Post a Comment