开发者

Test first subnode from node

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&开发者_Python百科gt;
        <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>   

How to test first <submode> from each <mode> (i need get numbers: 1, 7, 14) in such construction:

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

I do not understand how use position() here.


It is not generally true that

position() = 1

evaluates to true() if the current node has a parent mode and the current node is the first submode child of its parent.

position() specifies the position of the current node-list and this is defined in a different way, depending on how the select attribute of <xsl:apply-templates> is specified.

For example (assuming that the provided XML has a top element that is the parent of the mode elements), if the template was selected when processingthe following:

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

then

position() = 1

is true only for the 3rd submode child of the first mode element.

One correct answer:

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

Or, recommended:

Have a separate template:

<xsl:template match="mode/submode[1]">

In this case no code within template is necessary to check if the current node is the first submode child -- this is already known to be so.


To count the number of submodes in the previous mode if and only if this is the first submode of the current mode, and avoid duplicating code between <xsl:template match="submode"> and <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>

Alternatively, you can do the count processing from the template for mode instead. That way, you will not need any special processing for the first 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>


Your <xsl:template match= should read "mode/submode[1]".

Then you'd have the first submode of every mode.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜