xmlstarlet:使用属性过滤掉元素

时间:2015-10-22 10:57:07

标签: xml xpath xmlstarlet

如何过滤掉某些类型的元素,这些元素没有具有魔术值的属性并保留文档的其余部分?所有这些都使用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>的直接后代,<project>的孩子时,它不起作用示例

我想要获得的是数据库,但所有<some>已移除,除了名为A

<database>

    <some name="A" />


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

</database>

问候

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:0)

编写一个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