从节点测试第一个子节点

时间:2010-04-23 12:31:40

标签: xslt xpath

XML:

    <mode>
        <submode>1</submode>
        <submode>2</submode>
        <submode>3</submode>
        <submode>4</submode>
        <submode>5</submode>
        <submode>6</submode>
        <submode>7</submode>
    </mode>
    <mode>
        <submode>7</submode>
        <submode>8</submode>
        <submode>9</submode>
        <submode>10</submode>
        <submode>11</submode>
        <submode>12</submode>
        <submode>13</submode>
    </mode>
    <mode>
        <submode>14</submode>
        <submode>15</submode>
        <submode>16</submode>
        <submode>17</submode>
        <submode>18</submode>
        <submode>19</submode>
        20</submode>
    </mode>   

如何在每个<submode>(我需要获得数字: 1,7,14 )中首先测试<mode>

<xsl:template match="submode">
    <xsl:if test="(parent::mode) and (...what?...)">
        ...
    </xsl:if>
    ...
</xsl:template>

我不明白如何在这里使用position()。

3 个答案:

答案 0 :(得分:5)

通常不正确

position() = 1

如果当前节点具有父模式且当前节点是其父节点的第一个true()子节点,则

评估为submode

position()指定当前节点列表的位置,这是以不同的方式定义的,具体取决于select的{​​{1}}属性的来源指定。

例如(假设提供的XML有一个top元素是<xsl:apply-templates>元素的父元素),如果在处理以下内容时选择了模板:

mode

然后

<xsl:apply-templates select="/*/mode/submode[. = 3]"/>

仅适用于第一个position() = 1元素的第3个submode子元素。

一个正确答案:

mode

或推荐

有一个单独的模板:

parent::mode and not(preceding-sibling::submode)

在这种情况下,模板中的代码不需要检查当前节点是否是第一个<xsl:template match="mode/submode[1]">子节点 - 这已经知道了。

答案 1 :(得分:1)

要计算之前submodemode的数量,当且仅当这是当前submode的第一个mode时,并避免在<xsl:template match="submode">之间重复代码{1}}和<xsl:template match="submode[1]">

<!-- Special processing for first submode -->
<xsl:template match="submode[1]">
    <xsl:variable name="previousSubmodes" 
                  select="count(../preceding-sibling::mode/submode)"/>

    <!-- ... Do stuff with count ... -->

    <!-- Perform regular submode processing -->
    <xsl:call-template name="submode"/>

</xsl:template>

<!-- Regular processing for submodes -->
<xsl:template match="submode" name="submode">
    <!--  ... Do whatever ... -->
</xsl:template>

或者,您可以从mode的模板进行计数处理。这样,您就不需要对第一个submode进行任何特殊处理。

<xsl:template match="mode">
    <!-- ... Other processing ... -->

    <xsl:variable name="previousSubmodes" 
                  select="count(preceding-sibling::mode/submode)"/>

    <!-- ... Do stuff with count ... -->

    <!-- Handle submodes; could use select="node()|@*" instead to process 
         everything, not just submodes  -->
    <xsl:apply-templates select="submode"/>

</xsl:template>

<xsl:template match="submode">
    <!--  ... Do whatever ... -->
</xsl:template>

答案 2 :(得分:0)

您的<xsl:template match=应该阅读"mode/submode[1]"

然后您将获得每个submode的第一个mode