Ansari
Ansari

Reputation: 58

How to get the position of attribute through position()

input XML:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
    <p class="ABC">data</p>
    <p class="ABC">data</p>
    <p class="ABC">data</p>
    <p class="XYZ">data</p>
    <p class="XYZ">data</p>
    <p class="XYZ">data</p>
    <p class="ZXY">data</p>
    <p class="ZXY">data</p>
    <p class="ABC">data</p>
    <p class="ABC">data</p>
</xml>

My exception is i want create the element name with the help of attribute value then find the position of @class attribute:

<?xml version="1.0" encoding="UTF-8"?>
<root class="xml">
    <ABC no="1">data</ABC>
    <ABC no="2">data</ABC>
    <ABC no="3">data</ABC>
    <XYZ no="1">data</XYZ>
    <XYZ no="2">data</XYZ>
    <XYZ no="3">data</XYZ>
    <ZXY no="1">data</ZXY>
    <ZXY no="2">data</ZXY>
    <ABC no="4">data</ABC>
    <ABC no="5">data</ABC>
</root>

My XSL CODE but i am not able to find the position of @class attribute, please look in to this.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="xml">
        <root>
            <xsl:attribute name="class" select="local-name()"/>
            <xsl:apply-templates/>
        </root>
    </xsl:template>

    <xsl:template match="p">
        <xsl:variable name="po" select="position()"/>
        <xsl:element name="{@class}">
            <xsl:attribute name="no">
                <xsl:value-of select="preceding-sibling::p/@class/[position()"/>
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 0

Views: 136

Answers (1)

Michael Kay
Michael Kay

Reputation: 163322

You're making the mistake of assuming that the concept you call position (the "position of an attribute") is somehow related to what the position() function does. Just because they have the same name doesn't mean they do the same thing.

I would do this with xsl:number:

<xsl:template match="p">
    <xsl:element name="{@class}">
        <xsl:attribute name="no">
            <xsl:variable name="CLASS" select="@class"/>
            <xsl:number count="p[@class = $CLASS]"/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

Not tested.

Note that your question is a classic example of an XY question (https://en.wikipedia.org/wiki/XY_problem) where instead of asking "How do I achieve X?", you ask "How do I use the Y function?", assuming that using Y will help you to achieve X when this is not actually the case.

Upvotes: 3

Related Questions