如何使用 xslt 和样式表和 xsltproc 从 xml 中删除元素?

我有很多 XML 文件,它们的格式是:

<Element fruit="apple" animal="cat" />

我想把它从文件中删除。

使用 XSLT 样式表和 Linux 命令行实用程序 xsltproc,我如何做到这一点?

在这个脚本中,我已经有了包含要删除的元素的文件列表,因此可以将单个文件用作参数。


编辑: 这个问题最初是缺乏意图的。

我试图实现的是删除整个元素“ Element”,其中(water = = “ apple”& & Animal = = “ cat”)。在同一个文档中有许多名为“ Element”的元素,我希望保留这些元素。那么

<Element fruit="orange" animal="dog" />
<Element fruit="apple"  animal="cat" />
<Element fruit="pear"   animal="wild three eyed mongoose of kentucky" />

会变成:

<Element fruit="orange" animal="dog" />
<Element fruit="pear"   animal="wild three eyed mongoose of kentucky" />
104306 次浏览

使用最基本的 XSLT 设计模式之一: “覆盖 身份转换”只需要编写以下代码:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:output omit-xml-declaration="yes"/>


<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>


<xsl:template match="Element[@fruit='apple' and @animal='cat']"/>
</xsl:stylesheet>

请注意 第二个模板如何仅为名为“ Element”的元素覆盖标识(1st)模板,这些元素的属性“ Fruit”的值为“ apple”,属性“ Animal”的值为“ cat”。这个模板的主体是空的,这意味着被匹配的元素被简单地忽略(当它被匹配时没有产生任何东西)。

将此转换应用于下列源 XML 文档时:

<doc>...
<Element name="same">foo</Element>...
<Element fruit="apple" animal="cat" />
<Element fruit="pear" animal="cat" />
<Element name="same">baz</Element>...
<Element name="same">foobar</Element>...
</doc>

产生了想要的结果:

<doc>...
<Element name="same">foo</Element>...
<Element fruit="pear" animal="cat"/>
<Element name="same">baz</Element>...
<Element name="same">foobar</Element>...
</doc>

可以找到更多使用和重写标识模板的代码片段 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳

@ Dimitre Novatchev的答案当然既正确又优雅,但是有一个泛化(OP 没有问到) : 如果您想要过滤的元素也有您想要 留着的子元素或文本,该怎么办?

我相信这个微小的变化涵盖了这种情况:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0">


<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>


<!-- drop DropMe elements, keeping child text and elements -->
<xsl:template match="DropMe">
<xsl:apply-templates/>
</xsl:template>


</xsl:stylesheet>

要指定其他属性等等,匹配条件可能很复杂,如果要删除其他内容,可以使用多个这样的模板。

所以这个输入:

<?xml version="1.0" encoding="UTF-8"?>
<mydocument>
<p>Here's text to keep</p>
<p><DropMe>Keep this text but not the element</DropMe>; and keep what follows.</p>
<p><DropMe>Also keep this text and <b>this child element</b> too</DropMe>, along with what follows.</p>
</mydocument>


产生这样的输出:

<?xml version="1.0" encoding="UTF-8"?><mydocument>
<p>Here's text to keep</p>
<p>Keep this text but not the element; and keep what follows.</p>
<p>Also keep this text and <b>this child element</b> too, along with what follows.</p>
</mydocument>

归功于 XSLT 食谱