使用sed命令取消注释xml块

时间:2014-04-23 12:47:47

标签: xml bash sed

我有xml文件,其中有许多元素已注释。从所有这些元素中,我想使用sed命令取消注释一个元素。

我有xml文件:

<!-- This is the sample xml
    which holds the data of the students -->
<Students>
    <!-- <student>
        <name>john</>
        <id>123</id>
    </student> -->
    <student>
        <name>mike</name>
        <id>234</id>
    </student>
    <!-- <student>
        <name>NewName</name>
        <id>NewID</id>
    </student> -->
</Students>

在上面的xml文件中,我想取消注释最后一个xml块,所以我的文件看起来像

<!-- This is the sample xml
    which holds the data of the students -->
<Students>
    <!-- <student>
        <name>john</>
        <id>123</id>
    </student> -->
    <student>
        <name>mike</name>
        <id>234</id>
    </student>
    <student>
        <name>NewName</name>
        <id>NewID</id>
    </student> 
</Students>

我完成了sed命令,但没有得到如何从最后一个块中删除<!---->的方法。是否可以取消注释<name>NewName的xml块?除了删除整行外,我没有找到任何东西。

编辑:我可以拥有<name><id>之外的许多xml元素,例如<address>, <city>, <class>,<marks>

2 个答案:

答案 0 :(得分:1)

不要使用sed。使用xsltproc

<!-- uncomment.xsl -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- this copies every input node unchanged -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <!-- this uncomments every comment that starts with a `<` -->
  <xsl:template match="comment()[substring(normalize-space(), 1, 1) = '&lt;']">
    <xsl:value-of select="." disable-output-escaping="yes" />
  </xsl:template>
</xsl:stylesheet>

在命令行上:

xsltproc -o output.xml uncomment.xsl input.xml

如果它正常工作,您可以获得输入XML:

<!-- This is the sample xml
    which holds the data of the students -->
<Students>
    <student>
        <name>john</name>
        <id>123</id>
    </student>
    <student>
        <name>mike</name>
        <id>234</id>
    </student>
    <student>
        <name>NewName</name>
        <id>NewID</id>
    </student>
</Students>

答案 1 :(得分:1)

这可能适合你(GNU sed):

sed -r '/<Students>/,/<\/Students>/{/<Students>/{h;d};H;/<\/Students>/!d;g;s/(.*)<!-- (.*) -->(.*)/\1\2\3/}' file

这会将Students数据存储在保留空间中,然后使用贪婪来查找<!---->的最后一次出现,并在打印数据之前将其删除。