我创建了一个XSLT样式表,用于查找节点并将其删除。这非常有效。我现在想检查是否存在某个节点,然后删除该节点(如果存在)。
所以我试图添加一个if语句,那就是我遇到了以下错误:
编译错误:文件dt.xls行 10元素模板
元素模板 仅允许作为样式表的子项
我想我理解错误但不确定如何绕过它。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="Ad">
<xsl:template match="node()|@*">
<xsl:if test="name-ad-size">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:template>
<xsl:template match="phy-ad-width"/>
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="codeListing sampleOutput"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:5)
通常,当人们第一次尝试XSLT时,他们认为它是一种语言,就像C#,Java,PHP一样。所有这些语言都用于告诉计算机该做什么。但是使用XSLT则相反,您可以根据规则告诉处理器您期望的输出。
有时,使用xsl:if
是好的。更常见的是,这是一个错误的迹象。 删除节点,元素或文本的技巧是创建一个不输出任何内容的匹配模板。像这样:
<!-- starting point -->
<xsl:template match="/">
<xsl:apply-templates select="root/something" />
</xsl:template>
<xsl:template match="name-ad-size">
<!-- don't do anything, continue processing the rest of the document -->
<xsl:apply-templates select="node() | @*" />
</xsl:template>
<!-- copy anything else -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
为什么这样做?简单地说,因为处理器遍历每个元素和节点,并首先查看最匹配的模板。节点<name-ad-size>
的最佳匹配是不输出任何内容的匹配,因此它会有效地删除它。其他节点不匹配,因此最终出现在“全部捕获”模板中。
注1:您收到的错误可能是因为您错误地将<xsl:template>
添加到另一个元素中。它只能放在根<xsl:stylesheet>
下,而不能放在其他地方。
注2:<xsl:template>
语句的顺序无关紧要。处理器将使用所有这些来找到最佳匹配,无论它们放在何处(只要它们直接位于根目录下)。
编辑:有人神奇地检索了你的代码。以上是适用于完整样式表的故事:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="codeListing sampleOutput"/>
<!-- NOTE: it is better to have a starting point explicitly -->
<xsl:template match="/">
<xsl:apply-templates select="root/something" />
</xsl:template>
<!-- I assume now that you meant to delete the <Ad> elements -->
<xsl:template match="Ad">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
<!-- NOTE: here you were already deleting <phy-ad-width> and everything underneath it -->
<xsl:template match="phy-ad-width"/>
<!-- NOTE: copies everything that has no matching rule elsewhere -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>