嵌套元素的模板的 XSL 顺序



>我有一个这样的XML文件:

<text>
  <a>foo1</a>
  <a><b>foo2</b></a>
</text>

我有一个 XSL 文件,旨在使用模板 1 和 2 以不同的方式处理<a><a><b>

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
  <xsl:template match="text">
    <xsl:copy>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>
  <!-- t1 -->
  <xsl:template match="a">
    <xsl:element name="keep">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>
  <!-- t2 -->
  <xsl:template match="a/b" />
</xsl:stylesheet>

我预计这将产生:

<text>
  <keep>foo1</keep>
</text>

因为 t2 应该匹配并"忽略"<a><b>foo2</a></b>并且我认为它会优先于 t1(t1 和 t2 都匹配<a><b>但 t2 只是在 XSL 中较晚)。但输出实际上是:

<text>
  <keep>foo1</keep>
  <keep>foo2</keep>
</text>

事实上,如果我去掉 t2,输出是相同的,所以很明显它甚至不匹配<a><b>.我一定错过了什么:请问有人可以帮忙吗?

你要找的是

<xsl:template match="a[b]" />

一个模板,如果a元素具有名为 b 的子元素,则与这些元素匹配。

模板匹配,例如

<xsl:template match="a/b" />

不匹配a元素,它匹配ba元素作为其父元素的元素。但是在原始样式表中,永远不会提示 XSLT 处理器为b元素查找匹配的模板,这就是此模板中包含的代码(无)永远不会执行的原因。

通过此更改,输出为

<?xml version="1.0" encoding="UTF-8"?>
<text>
  <keep>foo1</keep>
</text>

如您所见,它几乎是您预期的输出。对于 XSLT 处理器 MSXSL,空行可能甚至不存在,因为 MSXSL 会去除仅空格节点的树。但是要让您的样式表在任何处理器上产生一致的结果,下面的信息仍然很有用。

若要删除输出中的空行,请将xsl:strip-space添加为顶级元素。此外,如果事先知道元素名称,则省去键入xsl:element name=...的麻烦。整个样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
  <xsl:template match="text">
    <xsl:copy>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>
  <!-- t1 -->
  <xsl:template match="a">
    <keep>
      <xsl:value-of select="."/>
    </keep>
  </xsl:template>
  <!-- t2 -->
  <xsl:template match="a[b]" />
</xsl:stylesheet>

相关内容

  • 没有找到相关文章