【问题标题】:Strange XSL matching behaviour奇怪的 XSL 匹配行为
【发布时间】:2017-11-14 08:12:43
【问题描述】:

有些关于 XSL 匹配规则的问题我无法获得。

我有这个输入:

<root>
  <metadata>
  </metadata>
  <elements>
    <a-elems>
          <a>A1</a>
          <a>A2</a>
    </a-elems>
    <b-elems>
      <b>B1</b>
      <b>B2</b>
    </b-elems>
  </elements>
</root>

这个 XSL 可以按我的意愿工作,报告了 &lt;a&gt; 值的列表:

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

    <xsl:template match = "/">
        _____ Elements _____
        <xsl:apply-templates select = "root/elements/*/*" />
    </xsl:template>


  <xsl:template match = "a-elems/a">
    __ A ELEM: <xsl:value-of select = "."></xsl:value-of> __
  </xsl:template>

  <xsl:template match="*">
        <xsl:message>Excluding <xsl:value-of select = "name(.)" /></xsl:message>
  </xsl:template>

</xsl:stylesheet>

但是,我认为这个根模板(我在其中声明了我想从哪个级别开始)会更简洁:

<xsl:template match = "/root/elements">
    _____ Elements _____
    <xsl:apply-templates select = "*/*" />
</xsl:template>

但它不起作用,我收到“排除根”消息,并且我知道模板永远不会匹配。我不明白为什么,我也尝试过 select = "*" 并添加优先级属性。

【问题讨论】:

    标签: xslt


    【解决方案1】:

    XSLT 将首先寻找与/(文档节点)匹配的模板。通过将匹配/ 的模板更改为/root/elements 将导致XSLT 使用它的built-in template rule 来匹配/。这个内置模板实际上是这样的:

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

    xsl:apply-templates 将选择子 root 节点。然后,这将与匹配 * 的模板匹配,因此您会收到您的消息,并且不再进行任何处理。

    最简单的解决方案是回到原来的状态。

    编辑:在回答您的评论时,您不必总是重新定义 /。您原始解决方案的另一个细微变化是这样做......

    <xsl:template match = "root">
        _____ Elements _____
        <xsl:apply-templates select = "elements/*/*" />
    </xsl:template>
    

    【讨论】:

    • 谢谢。我将使用有效的方法。它实践意味着您必须始终重新定义'/'?当您只对顶层以下的几个子树感兴趣时,我觉得这很奇怪。
    • 您不必总是重新定义/。我刚刚编辑了我的答案,稍作改动以进行演示。
    猜你喜欢
    • 2012-12-17
    • 2011-12-26
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多