我有这个XML:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<shortbody>
<text>
testing
</text>
<text>
shortbody
</text>
</shortbody>
<body>
<paragraph>
<text>
A new version of xsltransform.net is released!
</text>
</paragraph>
<paragraph>
<text>
We have added the following new features:
</text>
</paragraph>
</body>
</document>
这个XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="body">
<result>
<p>
<xsl:apply-templates select="//shortbody" />
</p>
<xsl:for-each select="paragraph">
<xsl:element name="paragraph">
<xsl:apply-templates select="."/>
</xsl:element>
</xsl:for-each>
</result>
</xsl:template>
<xsl:template match="body/paragraph/text | shortbody/text">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
结果是(see fiddle here):
<?xml version="1.0" encoding="UTF-8"?>
testing
shortbody
<result>
<p>
testing
shortbody
</p>
<paragraph>
A new version of xsltransform.net is released!
</paragraph>
<paragraph>
We have added the following new features:
</paragraph>
</result>
我无法理解为什么shortbody/text
的模板被调用两次所以它在我的XML之外结束,但是body/paragrap/text
没有被调用两次?我尝试了很多不同的匹配方法,但每次shortbody
都在我的XML元素之外。为什么这样,我如何更改我的XSLT,以便模板只匹配<xsl:template match="body">
内的调用?
答案 0 :(得分:2)
您需要添加另一个与根元素document
匹配的模板。
尝试添加此内容:
<xsl:template match="document">
<xsl:apply-templates select="body"/>
</xsl:template>
XML的根元素之外的文本是因为默认模板适用于根元素,它以递归方式处理子节点,最终复制文本节点。
答案 1 :(得分:1)
您看到的是built-in template rules的结果。由于您没有匹配/
或document
的模板,因此应用于document
的模板就是此内置模板:
<xsl:template match="document">
<xsl:apply-templates/>
</xsl:template>
这会将模板应用于document
的子级,包括shortbody
- 并且在没有匹配shortbody
的模板的情况下,默认模板相同:
<xsl:template match="shortbody">
<xsl:apply-templates/>
</xsl:template>
将模板应用于shortbody
的子项。
防止这种情况的一种方法是以这种方式组织样式表:
<xsl:template match="/document">
<result>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="shortbody">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="paragraph">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
请注意,缺少与body
和text
匹配的模板。在这里,内置模板规则完全符合要求。