XSLT当前节点,轴,点,自我等等。它们是什么?

时间:2016-09-26 12:32:40

标签: xslt xpath

我不确定我是否理解"轴"。

"轴定义相对于当前节点的节点集。" (http://www.w3schools.com/xsl/xpath_axes.asp)。 self选择当前节点。 "。"还选择当前节点。

self axis 包含上下文节点本身。自轴可以缩写为单个句点(。)。表达式self::*和。是等价的。 (http://docstore.mik.ua/orelly/xml/xslt/ch03_02.htm

因此,//*选择所有节点,//*[self::td]将其限制为树中当前节点下的td个节点。这听起来与.//td相同。但它不是。

   <!DOCTYPE html>
    <html>
    <head>
      <title>Not this</title>
    </head>
    <body>
      <table>
        <tbody>
          <tr>
            <td>
              <span>
                 <a>This is the title we want</a> 
              </span>
            </td>
          </tr>
      </tbody>
    </table>
    <p><span class="c2">not this.</span></p>
    <p><span class="c2">not this</span></p>
    <table>
      <tbody>
        <tr>
          <td width="235"><span class="c2">not this.</span></td>
        </tr>
      </tbody>
    </table>
    <table>
    <tbody>
    <tr>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
    </tr>
    <tr>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
    </tr>
    <tr>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
    </tr>
    <tr>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
    </tr>
    <tr>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
      <td class="c5"><span class="c4">not this</span></td>
    </tr>
  </tbody>
</table>
</body>
</html>

所以如果我运行这个XSLT,

<xsl:template match="body">
    <xsl:element name="chapter">
        <xsl:element name="title">
            <xsl:value-of select="( //*[self::td])[1]" /> 
        </xsl:element>
    </xsl:element>
</xsl:template>

然后我得到:

<chapter>
    <title>This is the title we want</title>
</chapter>

但如果我们跑:

<xsl:template match="body">
    <xsl:element name="chapter">
        <xsl:element name="title">
             <xsl:value-of select=".//td[1]"/>
        </xsl:element>
    </xsl:element>
</xsl:template>

然后我们得到:

<chapter>
    <title>This is the title we want not this. not this not this not this not this not this</title>
</chapter>

这很奇怪。我原本以为这两个应该是等价的。

<xsl:value-of select=".//p[1]"/>返回每个p元素的值。

<xsl:value-of select="( //*[self::p])[1]" />仅返回第一个p元素的内容。

为什么?

1 个答案:

答案 0 :(得分:1)

首先,这两个等效:

.//p

选择作为当前节点后代的每个p

//p

选择作为根节点后代的每个p - 即整个文档中的每个p

接下来,这个:

<xsl:value-of select=".//td[1]"/>

选择所有后代td元素,这些元素是其父的第一个td(参见:http://www.w3.org/TR/xpath/#path-abbrev)。

OTOH,这:

<xsl:value-of select="( //*[self::td])[1]" />

选择整个文档中所有td元素中的第一个元素。它可以更简单地写成:

<xsl:value-of select="(//td)[1]" />