XSLT value()和position()给出不正确的索引

时间:2014-01-06 13:57:03

标签: xml xslt

有人可以解释一下为什么我将下面的输出应用到xml文件中的xll文件。

<?xml version="1.0" encoding="ISO-8859-1"?>
<source>    
    <number>1</number> 
    <number>2</number> 
    <number>3</number> 
    <number>4</number> 
    <number>5</number> 
    <number>6</number> 
    <number>7</number> 
    <number>8</number> 
</source>

====================================

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match="number">
   <p>
   <xsl:value-of select="position()"/>
   <xsl:text> of </xsl:text>
   <xsl:value-of select="last()"/>
   </p>
</xsl:template>
</xsl:stylesheet>

======================================

<p>2 of 17</p> 
    <p>4 of 17</p> 
    <p>6 of 17</p> 
    <p>8 of 17</p> 
    <p>10 of 17</p> 
    <p>12 of 17</p> 
    <p>14 of 17</p> 
    <p>16 of 17</p> 

我不明白为什么输出不是8的中的2,而是2的8,依此类推。

3 个答案:

答案 0 :(得分:3)

@ColinE已经给出了一个很好的答案。我想添加另一种方法来绕过计算未明确定位模板的节点的问题。即不使用strip-space

匹配文档节点(源)并使用xsl:for-each元素,确保仅考虑number个元素。换句话说,多余的节点现在脱离了上下文。

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>

<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:template match="source">
  <xsl:for-each select="number">
     <p>
        <xsl:value-of select="position()"/>
        <xsl:text> of </xsl:text>
        <xsl:value-of select="last()"/>
     </p>
     <xsl:text>&#10;</xsl:text>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这给出了相同的输出:

<p>1 of 8</p>
<p>2 of 8</p>
<p>3 of 8</p>
<p>4 of 8</p>
<p>5 of 8</p>
<p>6 of 8</p>
<p>7 of 8</p>
<p>8 of 8</p>

另一方面,strip-space使您的输入看起来像这样:

<source><number>1</number><number>2</number><number>3</number><number>4</number><number>5</number><number>6</number><number>7</number><number>8</number></source>

现在,如果您将初始样式表应用于上述缺少任何空格的输入XML,您将获得与使用ColinE和我提出的解决方案时相同的结果。

答案 1 :(得分:2)

尝试添加条带空间,如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  <xsl:strip-space elements="*"/>
  <xsl:template match="number">
   <p>
   <xsl:value-of select="position()"/>
   <xsl:text> of </xsl:text>
     <xsl:value-of select="last()"/>
   </p>
</xsl:template>
</xsl:stylesheet>

这给出了以下输出:

<p>1 of 8</p>
<p>2 of 8</p>
<p>3 of 8</p>
<p>4 of 8</p>
<p>5 of 8</p>
<p>6 of 8</p>
<p>7 of 8</p>
<p>8 of 8</p>

这是由于空白问题造成的,如document所述。基本上,节点集包含与模板不匹配的空白节点,但对每个节点的索引有贡献。

答案 2 :(得分:0)

另一种选择是使用xsl:number。它比position()强大得多。 (在这个简单的例子中不需要xsl:number的附加功能,但很高兴知道。)

示例:

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

    <xsl:template match="number">
        <p>
            <xsl:number/>
            <xsl:text> of </xsl:text>
            <xsl:value-of select="../number[last()]"/>
        </p>
    </xsl:template>

</xsl:stylesheet>