xmlstarlet:过滤掉具有属性的元素

xmlstarlet: filter out element with attribute

如何过滤掉不具有魔法值属性的特定类型的元素并保留文档的其余部分?所有这些都使用 xmlstarlet?

我要说的是:

cat << EOF > database.xml
<?xml version="1.0"?>
<database>

    <some name="A" />
    <some name="B" />
    <some name="C" />
    <text>this is some text to be applied...</text>
    <project>
        <test deeper="structure"/>
    </project>

</database>
EOF

xmlstarlet sel -t -m "*" -c "*[not(self::some[@name != 'A'])]" database.xml

产量

<some name="A"/><text>this is some text to be applied...</text><project>
        <test deeper="structure"/>
    </project>

但这隐藏了我宝贵的<database>tag。除了 缩进 ,这不是问题...并且当 <some> 不是 <database> 的直系后代时不起作用,[=19] 的子代=] 例如。

我想要得到的是数据库的原样,但是所有 <some> 都被删除了 除了 名为 A:

的数据库
<database>

    <some name="A" />


    <text>this is some text to be applied...</text>
    <project>
        <test deeper="structure"/>
    </project>

</database>

问候

写一个 XSLT 样式表做

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

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

<xsl:template match="some[@name != 'A']"/>

</xsl:stylesheet>

然后调用 xmlstarlet 将该样式表应用于您的输入 XML:xmlstarlet tr sheet.xsl input.xml

不幸的是,xmlstarlet 的 sel 不支持 apply-templates,但您可以使用 ed 命令:

xmlstarlet ed -d '/database//some[@name != "A"]' input.xml