使用 sed 或 Perl 的正则表达式来注释 XML 块

Regex using sed or Perl to comment XML Block

我正在尝试仅使用 sedperl -pi(我唯一可用的工具)来评论 openAM 中位于 web.xml 的部分。

所以,我复制到这里:

  <servlet-mapping>
    <servlet-name>AgentConfigurationServlet</servlet-name>
    <url-pattern>/agentconfig/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>VersionServlet</servlet-name>
    <url-pattern>/ccversion/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>FSServlet</servlet-name>
    <url-pattern>/federation/*</url-pattern>
  </servlet-mapping>

但我试图只评论 <servlet-mapping>...</servlet-mapping>(但只有带有 /ccversion 的评论。我尝试了所有方法,但无法正常工作。

我尝试了什么:

sed -e "s/(<servlet-mapping>[\r\n]+.*[\r\n]+.*\/ccversion.*[\r\n]+.*)/<\!-- $1 -->/"

您应该使用 XML 感知工具来处理 XML。你提到 Perl,有几个 XML-处理模块可用。

但是,如果您坚持,请自行承担尝试以下操作的风险:

perl -0777 -pe 's{.*\K(<servlet-mapping>\s*.*?<url-pattern>/ccversion/.*?</servlet-mapping>)}{<!--  -->}s' file.xml
  • -0777以“slurp模式”读取文件,即读取整个文件,而不是逐行处理;
  • 初始 .*\K 用于匹配并忘记我们感兴趣的 <servlet-mapping> 之前的所有内容;
  • .*? 需要问号(“frugal quantifier”)只匹配最近的 <url-pattern>,同样第二个匹配到最近的 </servlet-mapping>,而不是匹配到最后一个;
  • 最后的 }s 修饰符更改点以匹配换行符。

顺便说一句,在xsh, a wrapper around XML::LibXML我碰巧维护,同样可以用

实现
open file.xml ;
for my $sm in //servlet-mapping[url-pattern="/ccversion/*"]
    xinsert comment {"$sm"} replace $sm ;
save :b ;    

因为有人不得不这么说,而我需要练习 :) 以下是使用 libxml 身份转换的方法:

comment.xsl

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/info/servlet-mapping[url-pattern[text()='/ccversion/*']]">
        <xsl:text disable-output-escaping="yes">&lt;!-- </xsl:text>
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        <xsl:text disable-output-escaping="yes"> --&gt;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

xsltproc comment.xsl input.xml

输出

<?xml version="1.0"?>
<info>
    <servlet-mapping>
        <servlet-name>AgentConfigurationServlet</servlet-name>
        <url-pattern>/agentconfig/*</url-pattern>
    </servlet-mapping>
    <!-- <servlet-mapping>
        <servlet-name>VersionServlet</servlet-name>
        <url-pattern>/ccversion/*</url-pattern>
    </servlet-mapping> -->
    <servlet-mapping>
        <servlet-name>FSServlet</servlet-name>
        <url-pattern>/federation/*</url-pattern>
    </servlet-mapping>
</info>