【问题标题】:Find and change two lines of text - regex查找和更改两行文本 - 正则表达式
【发布时间】:2018-12-06 01:45:18
【问题描述】:

我有一个 xml 文件,其中包括:

<init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>showServerInfo</param-name>
    <param-value>false</param-value>
</init-param>

我需要的是找到两行 Listings & true 并用 Listings & false 替换它

我想出的只是

sed -i 's/^<param-name>listings<\/param-name>\n<param-value>true<\/param-value>$/<param-name>listings<\/param-name><param-value>false<\/param-value>/g' somefile.xml

感谢您的任何建议。

【问题讨论】:

  • 为什么用sed解析XML,有像xmllint这样的语法感知工具
  • 您应该为此使用 XML 解析器!!! XSLT 也可能是一个很好的解决方案!
  • 给新手的建议:如果一个答案解决了您的问题,请点击旁边的大复选标记 (✓) 接受它,也可以选择投票(投票至少需要 15 个声望)点)。如果您发现其他答案有帮助,请给他们投票。接受和投票有助于未来的读者。请看【相关帮助中心文章】[1] [1]:stackoverflow.com/help/someone-answers

标签: regex xml bash sed


【解决方案1】:

我找到了解决方案。我无法使用 XSLT 或其他。解决我的问题的是简单的 awk。你的答案真的很棒而且很有用,肯定比我的解决方案更好,但我需要这种方式。

awk -i inplace '{
    if ($0 ~ /globaltag/) {
        r=1
    }
    if ($0 ~ /listings/) {
        if (r==1) {
            s=1
        }
    } else {
        if($0 ~ /true/) {
            if(s==1){ 
                sub(/true/,"false");
                s=0
                r=0
            }
        } else {
            s=0
        }
    }
    print;
}' file.xml

【讨论】:

    【解决方案2】:

    对于输入文件:

    $ more input.xml
    <root>
            <init-param>
                <param-name>listings</param-name>
                <param-value>true</param-value>
            </init-param>
            <init-param>
                <param-name>showServerInfo</param-name>
                <param-value>false</param-value>
            </init-param>
    </root>
    

    您可以使用以下 XSLT 样式表:

    $ more listing_conv.xslt 
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    
        <xsl:output method="xml" indent="yes" />
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="//init-param[./param-name = 'listings']/param-value">
            <param-value>false</param-value>
        </xsl:template>
    </xsl:stylesheet>
    

    说明:

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

    这部分将复制 XML 文件中的所有内容(默认行为),除非您到达 XPATH://init-param[./param-name = 'listings']/param-value

        <xsl:template match="//init-param[./param-name = 'listings']/param-value">
            <param-value>false</param-value>
        </xsl:template>
    

    第二部分将允许您将 param-value 的值更改为 false。

    因为 XPATH 将访问名称为 init-param 的元素,这些元素有一个名为 param-name 的子元素,其值设置为 listings。对于这些元素,您可以访问名为param-value 的子元素并将其覆盖为false

    输出:

    $ xsltproc listing_conv.xslt input.xml 
    <?xml version="1.0"?>
    <root>
      <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
      </init-param>
      <init-param>
        <param-name>showServerInfo</param-name>
        <param-value>false</param-value>
      </init-param>
    </root>
    

    我已经使用xsltproc 命令运行 XSLT proc,但您可以使用其他命令作为 xalan,或者您可以下载一个 saxon 解析器 jar:saxon9he.jar 并运行 java -jar saxon9he.jar &lt;attributes&gt;

    更多信息:

    I need a simple command line program to transform XML using an XSL Stylesheet

    【讨论】:

    • 先生,我还在学习中,必须向各位专家学习很多很多:)
    猜你喜欢
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多