Featured post
Transforming xml to xml using xslt encoded hierarchy problem xslt v1 -
in input xml file have got encoded hierarchy in elements attribute "lp":
<element lp="1"/> <element lp="1.1"/> <element lp="2"/> <element lp="3"/> <element lp="3.1" /> <element lp="3.2" /> <element lp="3.2.1" />
how transform xml data
<element lp="1"> <element lp="1.1"/> </element> <element lp="2"/> <element lp="3"> <element lp="3.1"/> <element lp="3.2"> <element lp="3.2.1"> </element> </element>
there way xslt2.0, have assumed xslt1.0 here.
one thing not xml not strictly valid, because lacks root element. purposes of answer, have assumed root element called elements
to achieve this, think need function determine 'level' of element. can done counting number of full stops in @lp attribute. in xslt1.0 have done removing full-stops text, , comparing resultant string length original string length
<xsl:variable name="level" select="string-length(@lp) - string-length(translate(@lp, '.', ''))" />
thus match top level elements this...
<xsl:apply-templates select="element[string-length(@lp) - string-length(translate(@lp, '.', '')) = 0]"/>
this match folllowing elements
<element lp="1."/> <element lp="2."/> <element lp="3."/>
next, each matched element, case of matching following elements where
- the @lp attribute begins current @lp attribute
- the level 1 more current level
this can done following select
<xsl:apply-templates select="following-sibling::element[substring(@lp, 1, $len) = $lp][string-length(@lp) - string-length(translate(@lp, '.', '')) = $level + 1]"/>
(note $len , $level variables containing length of current @lp attribute , current level)
putting altogether gives following xslt....
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:template match="/elements"> <elements> <xsl:apply-templates select="element[string-length(@lp) - string-length(translate(@lp, '.', '')) = 0]"/> </elements> </xsl:template> <xsl:template match="element"> <xsl:variable name="lp" select="@lp"/> <xsl:variable name="len" select="string-length(@lp)"/> <xsl:variable name="level" select="$len - string-length(translate(@lp, '.', ''))" /> <xsl:copy> <xsl:copy-of select="@lp"/> <xsl:apply-templates select="following-sibling::element[substring(@lp, 1, $len) = $lp][string-length(@lp) - string-length(translate(@lp, '.', '')) = $level + 1]"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
when applied following xml
<elements> <element lp="1"/> <element lp="1.1"/> <element lp="2"/> <element lp="3"/> <element lp="3.1"/> <element lp="3.2"/> <element lp="3.2.1"/> </elements>
produces following output
<elements> <element lp="1"> <element lp="1.1"/> </element> <element lp="2"/> <element lp="3"> <element lp="3.1"/> <element lp="3.2"> <element lp="3.2.1"/> </element> </element> </elements>
- Get link
- X
- Other Apps
Comments
Post a Comment