【问题标题】:Is it possible to comment/uncomment tags inside an xml file using xmlstarlet or other bash tools是否可以使用 xmlstarlet 或其他 bash 工具在 xml 文件中注释/取消注释标签
【发布时间】:2021-05-28 17:37:15
【问题描述】:

如何使用 xmlstarlet 或任何其他 shell 脚本库/工具等以编程方式在 xml 文件中注释/取消注释标记块。

评论中...

输入文件:

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

输出文件:

<note>
<to>Tove</to>
<!-- <from>Jani</from> -->
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

取消注释...

输入文件:

<note>
<to>Tove</to>
<!-- <from>Jani</from> -->
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

输出文件:

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

【问题讨论】:

  • @nahuel 的回答擅长评论但关于取消评论的问题:还有 '

标签: bash shell xmlstarlet


【解决方案1】:

可以用 xsltproc 完成

xsltproc  comment-from.xslt  input.xml

comment-from.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <!--Identity template,
    provides default behavior that copies all content into the output -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <!--More specific template for "from" that provides custom behavior -->
  <xsl:template match="from">
    <xsl:comment>
      <xsl:text><![CDATA[ <from>]]></xsl:text>
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
      <xsl:text><![CDATA[</from> ]]></xsl:text>
    </xsl:comment>
  </xsl:template>
</xsl:stylesheet>

【讨论】:

  • 感谢您的回答。它适用于评论,但您的答案中缺少未评论的部分。
  • 取消注释比较困难,因为注释必须被解析,并且创建节点无效,否则如果模式在一行,sed 命令会更简单
【解决方案2】:

在玩过 xlstproc 之后,我想出了一个取消注释案例的解决方案。 'contains' 函数可以解决问题...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <!--Identity template,
   provides default behavior that copies all content into the output -->
   <xsl:template match="@*|node()">
       <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
       </xsl:copy>
   </xsl:template>
   <!--More specific template for "from" that provides custom behavior -->
   <xsl:template match="comment()">

       <xsl:if test='contains(.,"&lt;from&gt;")' >
           <xsl:value-of  select="." disable-output-escaping="yes" />
       </xsl:if>

       <xsl:if test='not (contains(.,"&lt;from&gt;"))' > 
           <xsl:copy-of select="." />
       </xsl:if>

   </xsl:template>
</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 2015-09-19
    • 2018-05-07
    • 2012-12-08
    相关资源
    最近更新 更多