首页 > 解决方案 > 如何使用 sed 注释掉带有特定子标签的父 xml 标签?

问题描述

我有一个 xml 文件,如下所示。如果<name>xyz,则应将整个父<types>级注释掉。我怎样才能使用 sed 来实现这一点?

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="test">
    <types>
        <name>abc</name>
        <members>abc_member_1</members>
        <members>abc_member_2</members>
    </types>
    <types>
        <name>def</name>
        <members>def_member_1</members>
        <members>def_member_2</members>
        <members>def_member_3</members>
    </types>
    <types>
        <name>xyz</name>
        <members>xyz_member_1</members>
    </types>
    <version>1.0</version>
    <fullName>test</fullName>
<Package>

我试过使用它,它只适用于单行。

sed -i -e '/xyz/s/\(^.*$\)/<!--\1-->/' ./sample.xml
    rm -rf ./sample.xml-e

标签: xmlbashsed

解决方案


如果您可以忍受命名空间 URI 不是绝对的警告,则可以使用以下 XSLT-1.0 样式表(在修复</Package>结束标记之后)。

它只是将标识模板与模板结合使用以使用(并非所有 XSLT 处理器都支持)disable-output-escaping="yes"选项来注释掉相关<types>元素。形式上正确的方法是使用<xsl:comment>元素,但不幸的是它不支持元素树作为子元素(仅文本节点)。因此,在这种情况下,使用hackdisable-output-escaping 是唯一的选择

<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tst="test">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

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

    <xsl:template match="tst:types[tst:name='xyz']">
        <xsl:text disable-output-escaping="yes">&lt;!--</xsl:text>
            <xsl:copy-of select="." />
        <xsl:text disable-output-escaping="yes">--></xsl:text>
    </xsl:template>


</xsl:stylesheet>

最后一点:使用 XSLT 处理器处理 XML 文件总是比使用
or更好。xsltprocsedawk


推荐阅读