如果您安装了xmlstarlet,您可以尝试:
me@home$ xmlstarlet sel -t -m "//testable" -v trigger -o "|" -v message -o "|" -m sales-info -v san-a -o "|" -v san-b -o "|" -v san-c -n test.xml
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
命令分解:
xmlstarlet sel -t
-m "//testable" # match <testable>
-v trigger -o "|" # print out value of <trigger> followed by |
-v message -o "|" # print out value of <message> followed by |
-m sales-info # match <sales-info>
-v san-a -o "|" # print out value of <san-a> followed by |
-v san-b -o "|" # print out value of <san-b> followed by |
-v san-c # print out value of <san-c>
-n # print new line
test.xml # INPUT XML FILE
要定位在 内变化的标签<testable>
,您可以尝试以下返回所有叶节点的文本:
ma@home$ xmlstarlet sel -t -m "//testable" -m "descendant::*[not(*)]" -v 'text()' -i 'not(position()=last())' -o '|' -b -b -n test.xml
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
命令的Beakdown:
xmlstarlet sel -t
-m "//testable" # match <testable>
-m "descendant::*[not(*)]" # match all leaf nodes
-v 'text()' # print text
-i 'not(position()=last())' -o '|' # print | if not last item
-b -b # break out of nested matches
-n # print new line
test.xml # INPUT XML FILE
如果您无法访问xmlstarlet
,请查看您可以使用的其他工具。其他选项包括 xsltproc (请参阅mzjn 的答案)和xpath。
如果这些工具不可用,我建议使用更高级的语言(Python、Perl),它可以让您访问适当的 XML 库。
虽然可以使用 手动解析它regex
,但这样的解决方案并不理想†特别是在输入不一致的情况下。例如,以下(假设你有gawk
and sed
)接受你的输入,并应该输出预期的输出:
me@home$ gawk 'match($0, />(.*)</, a){printf("%s|",a[1])} /<\/testable>/{print ""}' test.xml | sed 's/.$//'
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
但是,如果输入格式发生变化,这将非常失败,因此不是我通常推荐的解决方案。