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

Popular posts from this blog

.htaccess - First slash is removed after domain when entering a webpage in the browser -

Automatically create pages in phpfox -

c# - Farseer ContactListener is not working -