Sunday, 28 September 2014

How to print Xpath of all nodes of an xml which contains values in it



How to print Xpath of all nodes of an xml which contains values in it. I have the XSLT which gives the xpath of all the nodes but does not checks for the value.


Example: The XML:



<products author="Jesper">
<product id="p1">
<name>Delta</name>
<price>800</price>
<stock>4</stock>
<country>Denmark</country>
</product>
<product id="p2">
<name>Golf</name>
<price>1000</price>
<stock>5</stock>
<country></country>
</product>
<product id="p3">
<name>Alfa</name>
<price>1200</price>
<stock>19</stock>
<country>Germany</country>
</product>
<product id="p4">
<name>Foxtrot</name>
<price></price>
<stock>5</stock>
<country>Australia</country>
</product>
</products>


When parsed through following XSLT:



<xsl:stylesheet version="1.0" xmlns:xsl="http://ift.tt/tCZ8VR">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable name="vApos">'</xsl:variable>

<xsl:template match="*[@* or not(*)] ">
<xsl:if test="not(*)">
<xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
<xsl:text>&#xA;</xsl:text>
</xsl:if>
<xsl:apply-templates select="@*|*"/>
</xsl:template>

<xsl:template match="*" mode="path">
<xsl:value-of select="concat('/',name())"/>
<xsl:variable name="vnumSiblings" select=
"count(../*[name()=name(current())])"/>
<xsl:if test="$vnumSiblings > 1">
<xsl:value-of select=
"concat('[',
count(preceding-sibling::*
[name()=name(current())]) +1,
']')"/>
</xsl:if>
</xsl:template>

<xsl:template match="@*">
<xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('[@',name(), '=',$vApos,.,$vApos,']')"/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>


Produces :



/products[@author='Jesper']
/products/product[1][@id='p1']
/products/product[1]/name
/products/product[1]/price
/products/product[1]/stock
/products/product[1]/country
/products/product[2][@id='p2']
/products/product[2]/name
/products/product[2]/price
/products/product[2]/stock
/products/product[2]/country
/products/product[3][@id='p3']
/products/product[3]/name
/products/product[3]/price
/products/product[3]/stock
/products/product[3]/country
/products/product[4][@id='p4']
/products/product[4]/name
/products/product[4]/price
/products/product[4]/stock
/products/product[4]/country


But I want it to produce :



/products[@author='Jesper']
/products/product[1][@id='p1']
/products/product[1]/name
/products/product[1]/price
/products/product[1]/stock
/products/product[1]/country
/products/product[2][@id='p2']
/products/product[2]/name
/products/product[2]/price
/products/product[2]/stock
/products/product[3][@id='p3']
/products/product[3]/name
/products/product[3]/price
/products/product[3]/stock
/products/product[3]/country
/products/product[4][@id='p4']
/products/product[4]/name
/products/product[4]/stock
/products/product[4]/country


Notice the omission of country in "p2" and price in "p4".


No comments:

Post a Comment