XSLT:如何获取所有子节点中特定节点的位置索引

时间:2014-03-01 07:11:21

标签: xml xslt xpath

考虑以下XML:

<root>
    <a>
        <pos>
            <c val="abc"></c>
            <c val="def"></c>
            <c val="ghi"></c>
            <c val="jkl"></c>
            <c val="mno"></c>
        </pos>
        <b>
            <c></c>
        </b>
        <b>
            <c></c>
            <d>here</d>
        </b>
        <b>
            <e>and</e>
            <c></c>
            <d>for</d>
        </b>
        <b>
            <c></c>
            <c></c>
            <d>also</d>
        </b>
    </a>
    <a>
        <pos>
            <c val="pqr"></c>
            <c val="stu"></c>
            <c val="vwx"></c>
            <c val="yz"></c>
        </pos>
        <b>
            <c></c>
            <d>what</d>
        </b>
        <b>
            <c></c>
        </b>
        <b>
            <d>how</d>
        </b>
        <b>
            <c></c>
            <d>where</d>
            <c></c>
        </b>
    </a>
</root>

现在在我的输出中,当我在<c></c>内遇到b时,我需要将val的{​​{1}}属性的相应值从<c></c>节点。通过相应的值,我的意思是<pos></pos>内的节点c的索引应该与所有pos节点中的c索引相同。

所需的输出是:

b

我尝试使用以下XSL:

<start>
    <level>
        abc
    </level>
    <level>
        def
        here
    </level>
    <level>
        and
        ghi
        for
    </level>
    <level>
        jkl
        mno
        also
    </level>
<start>


<start>
    <level>
        pqr
        what
    </level>
    <level>
        stu
    </level>
    <level>
        how
    </level>
    <level>
        vwx
        where
        yz
    </level>
 </start>

我需要做的是以某种方式获取所有<xsl:template match="root"> <star> <xsl:apply-templates select="a"/> </start> </xsl:template> <xsl:template match="a"> <xsl:apply-templates select="b"/> </xsl:template> <xsl:template match="b"> <level> <xsl:for-each select="*"> <xsl:choose> <xsl:when test="name() = 'd'"> <xsl:value-of select="."/> </xsl:when> <xsl:when test="name() = 'e'"> <xsl:value-of select="."/> </xsl:when> <xsl:when test="name() = 'c'"> <xsl:variable name="posCount"> <!-- I don't know what to do here --> </xsl:valiable> <xsl:for-each select="ancestor::a[1]/pos"> <xsl:for-each select="c[position() = $posCount]"> <xsl:value-of select="@val"/> </xsl:for-each> </xsl:for-each> </xsl:when> </xsl:choose> </xsl:for-each> </level> </xsl:template> 组合中每个c的位置数,然后使用相应位置b的{​​{1}}属性值来自val内部。

我该怎样继续这样做?

注意:我正在使用XSLT 1.0

Thnx提前!!

2 个答案:

答案 0 :(得分:6)

使用xsl:number元素可以非常轻松地获取您要查找的索引号。例如:

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

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

<xsl:template match="a">
    <start>
        <xsl:apply-templates select="b"/>
    </start>
</xsl:template>

<xsl:template match="b">
    <level>
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="*"/>
    </level>
</xsl:template>

<xsl:template match="d|e">
    <xsl:value-of select="."/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="b/c">
<xsl:variable name="i">
    <xsl:number count="b/c" from="a" level="any" />
</xsl:variable>
    <xsl:value-of select="ancestor::a/pos/c[number($i)]/@val"/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

</xsl:stylesheet>

注意:
1.我在输出中添加了一个root元素,使其成为有效的XML;
2.最好使用pos/c获取相应的值。

答案 1 :(得分:0)

我认为这样做:

<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>



<xsl:template match="/">
    <levels>
        <xsl:apply-templates select="//b[c]"/>
    </levels>
</xsl:template>

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

<xsl:template match="c">
    <xsl:variable name="pos" select="count(preceding::b/c) + count(preceding-sibling::c) + 1"/>
    <xsl:value-of select="//pos/c[$pos]/@val"/>
</xsl:template>

</xsl:stylesheet>