我有一个xml
<root>
<foo>Hello</foo>
<bar>World</bar>
</root>
和模板
<xsl:template match="foo">
<div>
<span><xsl:value-of select="." /></span>
<xsl:apply-templates select="//bar" mode="inner" />
</div>
</xsl:template>
<xsl:template match="bar">
<span><xsl:value-of select="." /></span>
</xsl:template>
<xsl:template match="bar" mode="inner">
<span><xsl:value-of select="." /></span>
</xsl:template>
期望
<div>
<span>Hello</span>
<span>World</span>
</div>
实际
<div>
<span>Hello</span>
<span>World</span>
</div><span>World</span>
我无法阻止块栏的输出。此模板在其他地方使用
<xsl:template match="bar" />
- 编辑 -
我无法覆盖根模板(它是不同的抽象级别)
<xsl:template match="/root">
<xsl:apply-templates />
</xsl:template>
我无法阻止使用模板 bar 。
<root>
<bar>World</bar>
</root>
期望
<span>World</span>
- 真实示例 -
模板
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output
method="xml"
version="1.0"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
omit-xml-declaration="yes"
media-type="text/html"
encoding="utf-8"
indent="yes"
/>
<xsl:template match="/root">
<html>
<head></head>
<body>
<xsl:apply-templates select="block[@place='main']"/>
</body>
</html>
</xsl:template>
<xsl:template match="block/page">
<div class="page-second">
<xsl:apply-templates select="//block/news" mode="inner" />
<div class="info">
<h1><xsl:value-of select="title" /></h1>
<xsl:value-of select="text" />
</div>
</div>
</xsl:template>
<xsl:template match="block/news">
<div class="clear" />
<div class="news-block">
<h2><xsl:value-of select="title" /></h2>
<ul>
<xsl:apply-templates select="article" />
</ul>
</div>
</xsl:template>
<xsl:template match="block/news" mode="inner">
<div class="news-block">
<h2><xsl:value-of select="title" /></h2>
<ul>
<li><a href="{article/link}"><xsl:value-of select="article/title" /></a></li>
</ul>
</div>
</xsl:template>
<xsl:template match="block/news/article">
<li><a href="{link}"><xsl:value-of select="title" /></a></li>
</xsl:template>
</xsl:stylesheet>
xml 1
<root>
<block place="main">
<page>
<title>Page title</title>
<text>Page text</text>
</page>
</block>
<block place="main">
<news>
<title>News title</title>
<article>
<title>Article 1 title</title>
<link>/article-1/</link>
</article>
<article>
<title>Article 2 title</title>
<link>/article-2/</link>
</article>
</news>
</block>
</root>
期待结果1
<html>
<head></head>
<body>
<div class="page-second">
<div class="news-block">
<h2>News title</h2>
<ul>
<li><a href="/article-1/">Article 1 title</a></li>
</ul>
</div>
<div class="info">
<h1>Page title</h1>
Page text
</div>
</div>
</body>
</html>
xml 2
<root>
<block place="main">
<news>
<title>News title</title>
<article>
<title>Article 1 title</title>
<link>/article-1/</link>
</article>
<article>
<title>Article 2 title</title>
<link>/article-2/</link>
</article>
</news>
</block>
</root>
结果2
<html>
<head></head>
<body>
<div class="clear" />
<div class="news-block">
<h2>News title</h2>
<ul>
<li><a href="/article-1/">Article 1 title</a></li>
<li><a href="/article-2/">Article 2 title</a></li>
</ul>
</div>
</body>
</html>
答案 0 :(得分:4)
您应该执行以下操作:
<xsl:template match="/">
<xsl:apply-templates select="//foo"/>
</xsl:template>
<xsl:template match="foo">
<div>
<span><xsl:value-of select="." /></span>
<xsl:apply-templates select="//bar" mode="inner" />
</div>
</xsl:template>
<xsl:template match="bar">
<span><xsl:value-of select="." /></span>
</xsl:template>
<xsl:template match="bar" mode="inner">
<span><xsl:value-of select="." /></span>
</xsl:template>
第一个模板(匹配/)将在根级别执行,如果不需要,则不会解析子元素。您的解决方案解析了所有内容并将正确的模板与之关联起来。
答案 1 :(得分:1)
看看你简单的“foo / bar”示例,你说当存在“foo”时,你想对后续的“bar”信封进行一些不同的处理,并且不希望其他模板为“ bar“在选择root的子元素时应用。
在这种情况下,您需要做的就是向XSLT添加模板,如果有“foo”元素则忽略“bar”元素(因为您知道在这种情况下匹配“foo”的模板正在处理它们另一个模板)。
<xsl:template match="bar[../foo]" />
现在,在您的实际示例中,“foo”元素是“block”元素,其中“page”元素作为子元素,而“bar”元素是“block”元素,其中“news”元素作为子元素。这意味着您只需要将此模板添加到现有的XSLT中。
<xsl:template match="block[news][../block/page]" />
或许,如果“地点”属性很重要
<xsl:template match="block[@place='main'][news][../block[@place='main']/page]" />
因此,它既有“页面”和“新闻”项目,也会停止正常处理“新闻”项目的“根”模板中的<xsl:apply-templates />
。
所有其他XSLT都可以保持原样,只需将上面的模板添加到它,它应该可以解决问题。
答案 2 :(得分:0)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<div>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="foo|bar">
<span>
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:stylesheet>