2

I was trying to find a way to convert the XML tags to their respective unique address like xPath. Nd I found an XSLT, where XML is processed and the unique address is created only for the nodes which doesnt have child elements and with attributes. [link]:Generate/get xpath from XML node java

XSLT :

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <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:value-of select="concat('=',$vApos,.,$vApos)"/>
         <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="vnumPrecSiblings" select=
         "count(preceding-sibling::*[name()=name(current())])"/>
        <xsl:if test="$vnumPrecSiblings">
            <xsl:value-of select="concat('[', $vnumPrecSiblings +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>

when passed to this

    <?xml version="1.0" encoding="UTF-8"?>
<root>
    <main>
        <tag1>001</tag1>
        <tag2>002</tag2>
        <tag3>
        <tag4>004</tag4>
        </tag3>
        <tag2>002</tag2>
        <tag5>005</tag5>
    </main>
</root>

produces

/root/main/tag1='001' /root/main/tag2='002' /root/main/tag3/tag4='004' /root/main/tag2[2]='002' /root/main/tag5='005'

So I need the xslt to generate in the following way

/root
/root/main
/root/main/tag1
/root/main/tag2
/root/main/tag3
/root/main/tag3/tag4
/root/main/tag2[2]
/root/main/tag5

Also I dont need values. So please help me with this

1 Answer 1

4

Your result could be produced rather simply by:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="*">
    <xsl:for-each select="ancestor-or-self::*">
        <xsl:value-of select="name()" />
        <xsl:variable name="i" select="count(preceding-sibling::*[name()=name(current())])"/>
        <xsl:if test="$i">
            <xsl:value-of select="concat('[', $i + 1, ']')"/>
        </xsl:if>
        <xsl:if test="position()!=last()">
            <xsl:text>/</xsl:text>
        </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="*"/>
</xsl:template>

</xsl:stylesheet>

Note that this does not process attributes (or any other type of nodes other than elements).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.