XPath递归下降在match和select之间表现不同

时间:2015-06-18 09:30:42

标签: xslt

信息

为什么

之间存在递归下降运算符的不同行为

●模板的匹配属性,忽略它们,只选择子项而忽略它们的后代

●for-each的select属性,它正常工作

给出了两个test.xsl示例,它们都在以下test.xml上运行。

的test.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>

<people>

  <person id="(1)">
    <name>Lucy</name>
  </person>  

  <class>

    <person id="(2)">
      <name>David</name>
      <person id="(21)">
        <name>David</name>
      </person>
    </person>

  </class>    

</people>

匹配= “//人”

在这个例子中,我们尝试使用match =“// person”来选择ALL 文件中的人物元素不起作用。代替 选择所有根后代人元素,人物元素 在其他人的元素内(如id =“(21)”)不是 包括在内。

test.xsl

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

  <xsl:template match="text()"/>  

  <xsl:template match="//person">
    <xsl:value-of select="@id"/>
  </xsl:template>

</xsl:stylesheet>

的Output.xml

(1)(2)

选择= “//人”

在这个例子中,我们使用select =“// person”来选择所有人 文件中的元素。这将正确选择所有根 后代人元素包括id =“(21)”。的价值 match =“class”是无关紧要的,因为select =“// person”使用绝对值 路径。

test.xsl

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

  <xsl:template match="text()"/>  

  <xsl:template match="class">
    <xsl:for-each select="//person">  
      <xsl:value-of select="@id"/>
    </xsl:for-each>  
  </xsl:template>

</xsl:stylesheet>

的Output.xml

(1)(2)(21)

2 个答案:

答案 0 :(得分:0)

template match本身不会导致任何处理和您的模板

  <xsl:template match="//person">
    <xsl:value-of select="@id"/>
  </xsl:template>

输出id属性,不进行进一步处理。所以你需要确保你有apply-templates例如

  <xsl:template match="//person">
    <xsl:value-of select="@id"/>
    <xsl:apply-templates/>
  </xsl:template>

或者你需要一个像

这样的模板
<xsl:template match="/">
  <xsl:apply-templates select="//person"/>
</xsl:template>

确保处理所有person个元素。

另请注意,match="//person"match="person"相同,因此您只需要

<xsl:template match="/">
  <xsl:apply-templates select="//person"/>
</xsl:template>

  <xsl:template match="person">
    <xsl:value-of select="@id"/>
  </xsl:template>

答案 1 :(得分:0)

匹配模式选择表达式之间存在差异。匹配模式不会选择任何内容 - 它仅用于查看当前节点是否与模式匹配。因此,匹配模式match="//person"match="person"相同。

如果一个节点永远不会成为当前节点(即模板不会应用),那么它是否与任何模板的匹配模式匹配并不重要不。这在第一个示例中显示:built-in template rules递归应用,直到遇到<person id="(2)">节点;这与更具体的模板的模式匹配 - 但该模板没有将模板应用于其任何后代的指令,因此此时链断开,并且从不检查节点<person id="(21)">以查看是否存在匹配它的模板。