首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >嵌套元素的XSL模板顺序

嵌套元素的XSL模板顺序
EN

Stack Overflow用户
提问于 2015-02-02 12:25:38
回答 1查看 862关注 0票数 1

我有一个类似于这样的XML文件:

代码语言:javascript
运行
复制
<text>
  <a>foo1</a>
  <a><b>foo2</b></a>
</text>

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

代码语言:javascript
运行
复制
<?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>

我希望这会产生:

代码语言:javascript
运行
复制
<text>
  <keep>foo1</keep>
</text>

因为t2应该匹配和“忽略”<a><b>foo2</a></b>,我认为它将优先于t1 ( t1和t2匹配<a><b>,但t2只是在XSL的后面)。但产出实际上是:

代码语言:javascript
运行
复制
<text>
  <keep>foo1</keep>
  <keep>foo2</keep>
</text>

事实上,如果我去掉t2,输出是相同的,所以很明显,它甚至不匹配<a><b>。我一定是遗漏了什么:谁能帮忙吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-02 12:31:28

你要找的是

代码语言:javascript
运行
复制
<xsl:template match="a[b]" />

如果a元素具有名为b的子元素,则该模板与它们匹配。

模板匹配,如

代码语言:javascript
运行
复制
<xsl:template match="a/b" />

不匹配a元素,它匹配以a元素作为其父元素的b元素。但是在原始样式表中,XSLT处理程序从未被提示为b元素找到匹配的模板,这就是为什么这个模板中包含的代码(无)从未被执行过。

通过此更改,输出为

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<text>
  <keep>foo1</keep>

</text>

正如您所看到的,它几乎是您所期望的输出。使用XSLT处理器MSXSL,空行可能不存在,因为MSXSL删除了仅使用空格的节点树。但是要让样式表在任何处理器上产生一致的结果,下面的信息仍然是有用的。

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

代码语言:javascript
运行
复制
<?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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28277741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档