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 submode
s 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
.
精彩评论