提问人:svidgen 提问时间:4/19/2013 最后编辑:Communitysvidgen 更新时间:11/12/2023 访问量:411072
如何从命令行漂亮地打印XML?
How to pretty print XML from the command line?
问:
相关:如何在 (unix) shell 脚本中漂亮打印 JSON?
是否有 (unix) shell 脚本以人类可读的形式格式化 XML?
基本上,我希望它转换以下内容:
<root><foo a="b">lorem</foo><bar value="ipsum" /></root>
...变成这样的东西:
<root>
<foo a="b">lorem</foo>
<bar value="ipsum" />
</root>
答:
来自 libxml2 的 xmllint
xmllint --format file.xml
(在基于 Debian 的发行版上安装 libxml2-utils 软件包)
从 XML::Twig perl 模块xml_pp
xml_pp < file.xml
(在基于 Debian 的发行版上安装 xml-twig-tools 软件包)
XMLStarlet
xmlstarlet format --indent-tab file.xml
整洁
tidy -xml -i file.xml
Python 的 xml.dom.minidom
echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
python -c 'import sys, xml.dom.minidom; print(xml.dom.minidom.parseString(sys.stdin.read()).toprettyxml())'
Saxon-lint(我自己的项目)
saxon-lint --indent --xpath '/' file.xml
撒克逊-HE
echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
java -cp /usr/share/java/saxon/saxon9he.jar net.sf.saxon.Query \
-s:- -qs:/ '!indent=yes'
西德尔
xidel --output-node-format=xml --output-node-indent -se . -s file.xml
(归功于 Reino)
所有命令的输出:
<root>
<foo a="b">lorem</foo>
<bar value="ipsum"/>
</root>
评论
echo '<xml .. />' | xmllint --some-read-from-stdn-option
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 805: ordinal not in range(128)
PYTHONIOENCODING="UTF-8"
cat some.xml | PYTHONIOENCODING="UTF-8" python -c 'import sys;import xml.dom.minidom;s=sys.stdin.read();print xml.dom.minidom.parseString(s).toprettyxml()' > pretty.xml
echo '<x></x><y></y>' | tidy -xml -iq
您没有提到文件,因此我假设您希望在命令行上提供 XML 字符串作为标准输入。在这种情况下,请执行以下操作:
$ echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' | xmllint --format -
xmllint --format yourxmlfile.xml
xmllint 是一个命令行 XML 工具,包含在 (http://xmlsoft.org/) 中。libxml2
================================================
注意:如果您没有安装 libxml2
,您可以通过执行以下操作来安装它:
CentOS 操作系统
cd /tmp
wget ftp://xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz
tar xzf libxml2-2.8.0.tar.gz
cd libxml2-2.8.0/
./configure
make
sudo make install
cd
Ubuntu的
sudo apt-get install libxml2-utils
天鹅云
apt-cyg install libxml2
MacOS操作系统
要使用 Homebrew 在 MacOS 上安装它,只需执行以下操作:brew install libxml2
Git的
如果你想要代码,也可以在 Git 上找到:git clone git://git.gnome.org/libxml2
评论
sudo apt-get install libxml2-utils
git
for Windows 下载甚至会安装最新版本的 .例:xmllint
"C:\Program Files\Git\usr\bin\xmllint.exe" --format [email protected] > [email protected]
xmllint --format in.xml > out.xml
您也可以使用 tidy,它可能需要先安装(例如在 Ubuntu 上:sudo )。apt-get install tidy
为此,您将发出如下内容:
tidy -xml -i your-file.xml > output.xml
注意:有许多额外的可读性标志,但自动换行行为有点烦人(http://tidy.sourceforge.net/docs/quickref.html)。
评论
tidy
对我来说也很有效。与此不同的是,这样做实际上是关闭标签。hxnormalize
<body>
tidy --indent yes --indent-spaces 4 --indent-attributes yes --wrap-attributes yes --input-xml yes --output-xml yes < InFile.xml > OutFile.xml
alias prettyxml='tidy --indent yes --indent-spaces 4 --indent-attributes yes --wrap-attributes yes --input-xml yes --output-xml yes | pygmentize -l xml'
curl url | prettyxml
for f in *.xml; do xmllint -o $f --format $f; done
正如丹尼尔·韦拉德(Daniel Veillard)所写:
我认为应该是安全的,因为解析器会将输入完全加载到树中 在打开输出进行序列化之前。
xmllint -o tst.xml --format tst.xml
缩进级别由环境变量控制,默认情况下为 2 个空格。如何将缩进更改为 4 个空格的示例:XMLLINT_INDENT
XMLLINT_INDENT=' ' xmllint -o out.xml --format in.xml
当您的XML文档被破坏时,您可能缺少选项。或者尝试使用严格的 XML 输出的弱 HTML 解析器:--recover
xmllint --html --xmlout <in.xml >out.xml
--nsclean
、 、 等可能有用。阅读手册页。--nonet
--nocdata
--noblanks
apt-get install libxml2-utils
dnf install libxml2
apt-cyg install libxml2
brew install libxml2
无需在macOS / 大多数Unix上安装任何东西。
用tidy
cat filename.xml | tidy -xml -iq
将使用 cat 查看文件重定向到 tidy,指定 xml 的文件类型,并在安静输出时缩进将抑制错误输出。JSON 也适用于 。-json
评论
cat
tidy -xml -iq filename.xml
tidy -xml -iq filename.xml
-m
我花了很长时间才找到在我的 Mac 上运行的东西。以下是对我有用的东西:
brew install xmlformat
cat unformatted.html | xmlformat
编辑:
免责声明:您通常应该更喜欢安装成熟的工具,例如完成这样的工作。XML/HTML 可能是一个可怕的残缺不全的混乱。但是,在某些情况下,使用现有工具比手动安装新工具更可取,并且可以肯定的是,XML 的源代码是有效的(足够)。我已经为其中一种情况编写了这个脚本,但它们很少见,所以在之前要谨慎。xmllint
我想添加一个纯粹的 Bash 解决方案,因为手动完成并不难,有时您不想安装额外的工具来完成这项工作。
#!/bin/bash
declare -i currentIndent=0
declare -i nextIncrement=0
while read -r line ; do
currentIndent+=$nextIncrement
nextIncrement=0
if [[ "$line" == "</"* ]]; then # line contains a closer, just decrease the indent
currentIndent+=-1
else
dirtyStartTag="${line%%>*}"
dirtyTagName="${dirtyStartTag%% *}"
tagName="${dirtyTagName//</}"
# increase indent unless line contains closing tag or closes itself
if [[ ! "$line" =~ "</$tagName>" && ! "$line" == *"/>" ]]; then
nextIncrement+=1
fi
fi
# print with indent
printf "%*s%s" $(( $currentIndent * 2 )) # print spaces for the indent count
echo $line
done <<< "$(cat - | sed 's/></>\n</g')" # separate >< with a newline
将其粘贴到脚本文件中,然后通过管道将 xml 传送。
这假定 xml 都在一行上,并且任何地方都没有多余的空格。人们可以很容易地在正则表达式中添加一些额外的东西来解决这个问题。\s*
评论
我会:
nicholas@mordor:~/flwor$
nicholas@mordor:~/flwor$ cat ugly.xml
<root><foo a="b">lorem</foo><bar value="ipsum" /></root>
nicholas@mordor:~/flwor$
nicholas@mordor:~/flwor$ basex
BaseX 9.0.1 [Standalone]
Try 'help' to get more information.
>
> create database pretty
Database 'pretty' created in 231.32 ms.
>
> open pretty
Database 'pretty' was opened in 0.05 ms.
>
> set parser xml
PARSER: xml
>
> add ugly.xml
Resource(s) added in 161.88 ms.
>
> xquery .
<root>
<foo a="b">lorem</foo>
<bar value="ipsum"/>
</root>
Query executed in 179.04 ms.
>
> exit
Have fun.
nicholas@mordor:~/flwor$
如果只是因为它“在”数据库中,而不是“只是”文件。在我看来,更容易合作。
相信其他人已经解决了这个问题。如果您愿意,毫无疑问,甚至可能在格式方面“更好”,或者同样好。eXist
xml
当然,您始终可以通过各种不同的方式查询数据。我尽可能保持简单。您也可以只使用 GUI,但您指定了控制台。
使用 xidel:
$ xidel -s input.xml -e . --output-node-format=xml --output-node-indent
$ xidel -s input.xml -e 'serialize(.,{"indent":true()})'
$ echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' | \
xidel -se . --output-node-format=xml --output-node-indent
$ echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' | \
xidel -se 'serialize(.,{"indent":true()})'
评论
xidel --help
-
xidel
这种简单的解决方案不提供压痕,但对人眼来说要容易得多。此外,它还允许通过简单的工具(如 grep、head、awk 等)更轻松地处理 xml。
用于将“<”替换为前面的换行符。sed
正如 Gilles 所提到的,在生产中使用它可能不是一个好主意。
# check you are getting more than one line out
sed 's/</\n</g' sample.xml | wc -l
# check the output looks generally ok
sed 's/</\n</g' sample.xml | head
# capture the pretty xml in a different file
sed 's/</\n</g' sample.xml > prettySample.xml
评论
sed
不是 XML 解析器
yq 可用于漂亮地打印 XML。 它有一个定义缩进的选项。
yq --input-format xml --output-format xml --indent 2
评论
yq --input-format xml --output-format xml
评论
xmllint
libxml2-utils
libxml2