查找xml标签并将标签内的文本替换为多次出现的参数值

查找xml标签并将标签内的文本替换为多次出现的参数值

查找特定的 xml 标签并将标签内的文本替换为某个参数化值。多次出现需要更换。

示例文件内容:

<a>abc</a>

目前的尝试:

sed -i "s/\(<a>\).*\(<\/a>\)/\(<a>\)$param\(<\/a>\)/g" script.xml

期望的结果:如果 param=111 那么

<a>111</a>

答案1

我知道您需要一种sed解决方案,但我通常推荐使用基于 XML 的工具(其中有很多),而不是sed在处理除非常简单的工具之外的 XML 文档时。

假设这是我的 XML 文档 ( doc.xml):

<?xml version="1.0"?>
<xml>
    <c><a>abc</a></c>
    <b>
        <a>abc</a>
        <a>abc</a>
    </b>
    <a parm="FPM">abc</a>
</xml>

我将使用以下 XML 样式表style.xsl将文档转换为所需的格式。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name = "value" />

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

    <xsl:template match="a/text()[.='abc']">
        <xsl:value-of select = "$value" />
    </xsl:template>

</xsl:stylesheet>

我使用xsltproc大多数主要 Linux 发行版上默认安装的工具来执行转换:

$ xsltproc --stringparam value "111" style.xsl doc.xml
<?xml version="1.0"?>
<xml>
    <c><a>111</a></c>
    <b>
        <a>111</a>
        <a>111</a>
    </b>
    <a parm="FPM">111</a>
</xml>
$

答案2

我编辑 XML 文件的首选工具是xmlstarlet.假设这是我的 XML 文档(doc.xml):

<?xml version="1.0"?>
<xml>
    <c><a>abc</a></c>
    <b>
        <a>abc</a>
        <a>abc</a>
    </b>
    <a parm="FPM">abc</a>
</xml>

这是xmlstarlet命令:

param=111
xmlstarlet edit --ps --update '//a' --value "$param" doc.xml

输出

<?xml version="1.0"?>
<xml>
    <c><a>111</a></c>
    <b>
        <a>111</a>
        <a>111</a>
    </b>
    <a parm="FPM">111</a>
</xml>

答案3

  1. 这些\(\)在你的情况下是多余的。写吧sed -i "s/<a>.*<\/a>/<a>$param<\/a>/g" script.xml
  2. 如果您的字符串包含/,则使用不同的分隔符会更容易阅读:sed -i "s_<a>.*</a>_<a>$param</a>_g" script.xml
  3. 该选项表明一行上g可以有多个标签。<a>这是一个问题: The.*将匹配下一个</a>、更多内容和最后一个<a>,因此请防止包含其他标签:sed -i "s_<a>[^<]*</a>_<a>$param</a>_g" script.xml
  4. <a>请注意,如果标签内嵌套有其他标签或$param包含特殊字符(例如"或),则此操作将不起作用\

答案4

我会在 Perl 中执行此操作,而不是sed因为 Perl 支持非贪婪匹配:

perl -i -pe "s|<a>.+?</a>|<a>$param</a>|g" file

这意味着“匹配最短的可能字符串”,因此这将找到 an和 an.+?之间的最短字符串。<a></a>

然而,我必须强调,即使在稍微复杂的 XML 文档上,这也很可能会失败,您确实应该考虑使用专用的 XML 解析器。

相关内容