0

Need your help in XPath or XSLT.

I'm new to both of them, but right now I have to solve a case that sounds like simple at the first time but after so many tries, hard for me to solve :)

I have the following (simplified) XML.

First, the "clean" one:

<root>
    <a>
        <a1>
            <a11>
                <x1>111</x1>
                <x2>222</x2>
                <x3>333</x3>
            </a11>
        </a1>
    </a> 
    <b>
        <b1>
            <b11>
                <b111>
                    <x2>777</x2>
                    <x3>888</x3>
                </b111>
            </b11>
        </b1>
    </b>
</root>

And the second one, the same XML but with additional "logical" ID numbers. These IDs helps crosscheck the result later, they physically doesn't exist in the XML.

<root>
1    <a>
    1    <a1>
        1    <a11>
            1    <x1>111</x1>
            2    <x2>222</x2>
            3    <x3>333</x3>
            </a11>
        </a1>
    </a> 
2    <b>
    1    <b1>
        1    <b11>
            1    <b111>
                1    <x2>777</x2>
                2    <x3>888</x3>
                </b111>
            </b11>
        </b1>
    </b>
</root>

My goal is, to retrieve the logical ID number of the current node and all it's parent, grandparent...so on (except the 'root' node) in sequence, starting from the current node.

For example, if my current node position is at root/a/a1/a11/x2, then I want to produce an output similiar like this:

Output: 2.1.1.1

where (in sequence, left to right):

'2' = 'x2' node
'1' = 'a11' node
'1' = 'a1' node
'1' = 'a' node

Right now, all I know is getting the current node ID number and it's one level parent above only, by using these XPath:

count(./preceding-sibling::*) + 1   
count(../preceding-sibling::*) + 1

But I still can't figure out how to get the rest (if any) of it's parents ID number. Since the node depth level of the XML are vary, and most of time are more than 2 level depth, then I have to cover that possibility also.

I hope my question is clear.

Please, anybody have a solution? It'll be very much helpful for a beginner like me if you can give some explanation on your solution too :)

Thank you.

4

1 回答 1

0

您可以使用ancestor-or-self轴来枚举节点的所有祖先,如下所示:

<xsl:for-each select="ancestor-or-self::*[position() &lt; last()]">
    <xsl:sort select="position()" data-type="number" order="descending"/>
    <xsl:value-of select="count(preceding-sibling::*) + 1"/>
    <xsl:if test="position() != last()">.</xsl:if>
</xsl:for-each>

对于节点root/a/a1/a11/x2,这将输出2.1.1.1

谓词[position() &lt; last()]用于排除根元素。xsl:sort用于以相反的文档顺序处理祖先。

于 2013-10-07T21:20:55.437 回答