漂亮打印XML(带属性对齐)

4
这是对如何使用命令行美化XML?的追加问题。
libxml2中,是否有任何工具可以使每个节点的属性对齐?我有一个大型XML文档,其逻辑结构我无法更改,但我想要排版。
<a attr="one" bttr="two" tttr="three" fttr="four"/>

转换为

<a attr   = "one"
   bttr   = "two"
   tttr   = "three"
   fttr   = "four"
   longer = "attribute" />
2个回答

3

xmllint有一个--pretty选项,支持三个级别的美化。如果输出如下:

<?xml version="1.0"?>
<a
    attr="one"
    bttr="two"
    tttr="three"
    fttr="four"
/>

如果你认为这样可以的话,请使用--pretty 2
xmllint --pretty 2 - <<< '<a attr="one" bttr="two" tttr="three" fttr="four"/>'

我的 xmllint 没有这个选项... 你用的是哪个版本?我正在使用 libxml version 20706 - Sean Allred
我正在使用 xmllint: using libxml version 20901 - hek2mgl
:( 这就是问题所在,我想。我的副本最后打包于2013年1月30日14:59... 唉。 - Sean Allred
几年过去了,虽然这是我找到的最好的答案,但它仍然相当糟糕。虽然它在属性方面表现得很好,但它完全破坏了其余元素的美观程度:xmllint --pretty 2 - <<< '<x><a attr="one" bttr="two" tttr="three" fttr="four"/><b>something</b></x>' 真是太可怕了。 - rbellamy
@rbellamy 我明白了。看起来很奇怪! :) 我想在这种情况下最好的做法是自己编写一些代码..(或修改现有的代码美化工具) - hek2mgl

1

尝试使用样式“-s cvs”的xml_pp

您需要libxml2中的某些内容,但我不知道具体是什么。如果您愿意使用其他内容,请继续阅读以下内容。

xml_ppXML::Twig 库的一部分,它有许多不同的预配置样式。

您可以通过“-s”(样式)参数指定样式。

如果只留空“-s”,则会显示所有可用的样式。 (实际上,它会动态生成该列表。因此保证是最新的。)

$ xml_pp -s
Use of uninitialized value $opt{"style"} in hash element at /usr/bin/xml_pp line 100.
usage: /usr/bin/xml_pp [-v] [-i<extension>] [-s (none|nsgmls|nice|indented|indented_close_tag|indented_c|wrapped|record_c|record|cvs|indented_a)] [-p <tag(s)>] [-e <encoding>] [-l] [-f <file>] [<files>] at /usr/bin/xml_pp line 100.

下面是更美观的列表格式。 事实证明,我安装的版本支持11种格式:

$ xml_pp -s 2>&1 | grep -Po '(?<=\[-s \()[^)]*' -o | tr '|' '\n' | nl
     1  none
     2  nsgmls
     3  nice
     4  indented
     5  indented_close_tag
     6  indented_c
     7  wrapped
     8  record_c
     9  record
    10  cvs
    11  indented_a

让我们尝试它们全部。

这是我们的输入文件:

$ cat in.xml
<a attr="one" bttr="two" tttr="three" fttr="four"/>

以下是所有的样式:

$ for STYLE in $(echo "none nsgmls nice indented indented_close_tag indented_c wrapped record_c record cvs indented_a"); do echo; echo "==> Style: xml_pp -s $STYLE <=="; cat in.xml | xml_pp -s $STYLE | tee out.xml_pp.$STYLE.xml; echo; done

==> Style: xml_pp -s none <==
<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s nsgmls <==
<a
attr="one"
bttr="two"
fttr="four"
tttr="three"
/>

==> Style: xml_pp -s nice <==
<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s indented <==
<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s indented_close_tag <==
<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s indented_c <==
<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s wrapped <==
<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s record_c <==

<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s record <==

<a attr="one" bttr="two" fttr="four" tttr="three"/>

==> Style: xml_pp -s cvs <==
<a
    attr="one"
    bttr="two"
    fttr="four"
    tttr="three"
/>

==> Style: xml_pp -s indented_a <==
<a
    attr="one"
    bttr="two"
    fttr="four"
    tttr="three"
/>

对于这个小输入文件,这些样式中的许多是等效的。它们产生相同的输出:

$ sha256sum * | sort
452f5c19177d9cc6a54589168dbb1ee790c783a963110662e7dfae170bf997e4  out.xml_pp.cvs.xml
452f5c19177d9cc6a54589168dbb1ee790c783a963110662e7dfae170bf997e4  out.xml_pp.indented_a.xml
8e119bb50bcbf3d72159c96139cf328f46a0de259410acdd344f26e52f033996  out.xml_pp.nsgmls.xml
d1ed9a4d1ebf8b9f1d012577809909e91e1ba0fc01b5afc8ff1302ca9dced617  out.xml_pp.record_c.xml
d1ed9a4d1ebf8b9f1d012577809909e91e1ba0fc01b5afc8ff1302ca9dced617  out.xml_pp.record.xml
e0d13f80ddc48876678c62e407abd3ab1eac8481a82d5aabb1514e24aee4717c  in.xml
ea90003eab0ba71936a8a329a87b079b4fb120fe6873d4fa9bc8f986e8654b45  out.xml_pp.indented_close_tag.xml
ea90003eab0ba71936a8a329a87b079b4fb120fe6873d4fa9bc8f986e8654b45  out.xml_pp.indented_c.xml
ea90003eab0ba71936a8a329a87b079b4fb120fe6873d4fa9bc8f986e8654b45  out.xml_pp.indented.xml
ea90003eab0ba71936a8a329a87b079b4fb120fe6873d4fa9bc8f986e8654b45  out.xml_pp.nice.xml
ea90003eab0ba71936a8a329a87b079b4fb120fe6873d4fa9bc8f986e8654b45  out.xml_pp.none.xml
ea90003eab0ba71936a8a329a87b079b4fb120fe6873d4fa9bc8f986e8654b45  out.xml_pp.wrapped.xml

这些样式都不完全符合您的要求。

但是 "cvs" 很接近。(而 "indented_a" 产生的输出完全相同。)

后记:有点脏

后记:输出感觉有点脏。

(a)一些文件开头没有什么好理由就是空行...

$ grep '^$' * -n
out.xml_pp.record_c.xml:1:
out.xml_pp.record.xml:1:
(b)...而且有些文件根本没有行终止符:
$ file *
in.xml:                            ASCII text
out.xml_pp.cvs.xml:                ASCII text
out.xml_pp.indented_a.xml:         ASCII text
out.xml_pp.indented_close_tag.xml: ASCII text, with no line terminators
out.xml_pp.indented_c.xml:         ASCII text, with no line terminators
out.xml_pp.indented.xml:           ASCII text, with no line terminators
out.xml_pp.nice.xml:               ASCII text, with no line terminators
out.xml_pp.none.xml:               ASCII text, with no line terminators
out.xml_pp.nsgmls.xml:             ASCII text
out.xml_pp.record_c.xml:           ASCII text
out.xml_pp.record.xml:             ASCII text
out.xml_pp.wrapped.xml:            ASCII text, with no line terminators

-- 问题似乎在于xml_pp没有在最后一行加上换行符。所以,如果你只有一行内容,那么就不会有换行符。这非常奇怪。

看起来是这样的:

$ wc --lines *
  5 out.xml_pp.cvs.xml
  5 out.xml_pp.indented_a.xml
  0 out.xml_pp.indented_close_tag.xml
  0 out.xml_pp.indented_c.xml
  0 out.xml_pp.indented.xml
  0 out.xml_pp.nice.xml
  0 out.xml_pp.none.xml
  5 out.xml_pp.nsgmls.xml
  1 out.xml_pp.record_c.xml
  1 out.xml_pp.record.xml
  0 out.xml_pp.wrapped.xml
 17 total

以下是我喜欢添加尾部换行符(0x0A字节)的方法,如果没有,请参考:

$ mkdir 1; mv out.*.xml 1/; cp -r 1/ 2/

$ pcregrep -LMr '\n\Z' 2/ | xargs -n1 --no-run-if-empty -- sed -i -e '$a\' --

$ diff --recursive 1/ 2/ | head
diff --recursive 1/out.xml_pp.cvs.xml 2/out.xml_pp.cvs.xml
6c6
< />
\ No newline at end of file
---
> />
diff --recursive 1/out.xml_pp.indented_a.xml 2/out.xml_pp.indented_a.xml
6c6
< />
\ No newline at end of file

看起来后面是这样的:
$ cd 2/

$ wc --lines *
  6 out.xml_pp.cvs.xml
  6 out.xml_pp.indented_a.xml
  1 out.xml_pp.indented_close_tag.xml
  1 out.xml_pp.indented_c.xml
  1 out.xml_pp.indented.xml
  1 out.xml_pp.nice.xml
  1 out.xml_pp.none.xml
  6 out.xml_pp.nsgmls.xml
  2 out.xml_pp.record_c.xml
  2 out.xml_pp.record.xml
  1 out.xml_pp.wrapped.xml
 28 total

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接