一种更简单,更短和更通用的(无元素名称硬编码)溶液:
<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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*[not(*[2])]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/*/*/node()"/>
</xsl:stylesheet>
当该变换是在第一提供的XML文档施加(纠正成良构):
<root>
<branch>
<foo>bar</foo>
</branch>
</root>
有用,正确的结果产生:
<branch></branch>
当相同的变换在第二提供的XML文档(再次需要用于良好性将被校正)施加:
<root>
<branch>
<foo>bar</foo>
</branch>
<branch>
<foo>baz</foo>
</branch>
</root>
再次通缉,产生正确的输出:
<root>
<branch></branch>
<branch></branch>
</root>
说明:
的identity rule副本的每个节点 “原样”。
有两个模板覆盖特定节点的标识模板并以不同方式处理这些节点。
第一个覆盖模板匹配没有第二个元素子元素的顶层元素。它不会复制元素本身,而是处理其子元素。
第二个重写模板匹配顶层元素的大子元素的任何元素。该模板没有一个机构,这意味着所有这些匹配元素被忽略,且不包含在输出(换句话说 - “删除”)
请注意:
无论文档中的元素名称如何,此转换都可以应用于任何 XML文档,并且仍会生成所需的正确结果。
例如,当该XML文档上施加:
<t>
<b>
<f>brrr</f>
</b>
<b>
<f>bzzz</f>
</b>
</t>
有用,正确的结果产生:
<t>
<b></b>
<b></b>
</t>
对比度这由当前所产生的结果 - 接受的答案:
<t>
<b>
<f>brrr</f>
</b>
<b>
<f>bzzz</f>
</b>
</t>
+1谢谢,似乎在我的沙箱里工作。我只是在学习XSLT:像[*和不...]这样的正则表达式需要XSLT 2.0吗? – msi 2012-03-18 14:05:02
仅在XSLT和XPath 2.0中支持字符串匹配的正则表达式。然而,我只使用XSLT 1.0元素匹配模式作为match =“root [* [2]]”'只是'match =“root [child :: * [2]]的简写形式''意思是匹配'root '具有至少两个任何名字的子元素的元素。 – 2012-03-18 14:18:00