删除xml文件中两个标记之间的EOL和空格

时间:2013-04-10 16:06:32

标签: xml bash formatting

我有很多(超过50个)xml文件,其中包含一些行(每个文件超过30/40)且格式不正确:

例如,这个:

<TAG1>
    <TAG_TO_FORMAT>
           a_random_string

    </TAG_TO_FORMAT>
    <AN_OTHER_TAG_TO_FORMAT>
                       an_other_random_string
    </AN_OTHER_TAG_TO_FORMAT>
    <OTHER_TAG>pifpafpouf</OTHER_TAG>

</TAG1>

应该转变为:

<TAG1>
    <TAG_TO_FORMAT>a_random_string</TAG_TO_FORMAT>
    <AN_OTHER_TAG_TO_FORMAT>an_other_random_string</AN_OTHER_TAG_TO_FORMAT>
    <OTHER_TAG>pifpafpouf</OTHER_TAG>

</TAG1>

如果</TAG1>之前的新行仍然存在并不重要,我的关键问题是每个模式:<TAG>random_string</TAG>必须在一行上(random_string不包含EOL)< / p>

我在bash中找不到允许我执行此操作的任何工具,所以我怎么能在bash中执行此操作? (或者可能在python中,但我更喜欢bash)。

4 个答案:

答案 0 :(得分:3)

有像xmllint和tidy这样的命令行工具可以像这样使用:

tidy -xml -iq somefile.xml

理论上xmllint也可以这样做,但是xmllint不能像我在OS X上描述的那样工作(暂时没有Linux实例可以在那里进行测试):

xmllint --noblanks somefile.xml

答案 1 :(得分:0)

我建议将Perl用于此类任务。

#!/usr/bin/env perl

use strict;
use warnings;

my $text = join "", <>; 
$text =~ s/>\s+([^\s].*?[^\s])\s+<\//>$2<\//;
print "$text";

这样称呼:

my.pl < input.xml > output.xml

答案 2 :(得分:0)

嗯,你可以用sed:

来做
x='TAG_TO_FORMAT'
sed -e '/<'"$x"'>/{:next;/<\/'"$x"'>/!{N;bnext;};s/\n//g;s/>\s*/>/;s/\S\s*</</;}'

当一行以正确的标记开头时,我们进入循环收集行,直到找到结束标记。然后我们擦除所有换行符并清理由&gt;锚定的空格。一边,&lt;另一方面。

答案 3 :(得分:0)

Tidy做得很合理。另一个选择是引发xslt转换,调用normalize-space()

main2.o

我会将其保存到文件中,如果从命令行运行

main2

或在管道中

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="@*|node()|/">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()">
            <xsl:sort select="@kname"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>
<xsl:template match="text()">
    <xsl:value-of select="normalize-space(text())"/>
</xsl:template>

xmllint --noblanks不能将我想要的所有空格字符都描述为“可忽略”。从技术上讲几乎可以肯定是正确的,但不是我想要的。