使用xmlstarlet处理多个xml元素
我正试图编写一个bash脚本,从一个xml文件中提取多个“控制器”,并用一个管道(即Tom Tykwer | Andy Wachowski)将它们分隔开 相关的xml部分是:使用xmlstarlet处理多个xml元素,xml,bash,xmlstarlet,Xml,Bash,Xmlstarlet,我正试图编写一个bash脚本,从一个xml文件中提取多个“控制器”,并用一个管道(即Tom Tykwer | Andy Wachowski)将它们分隔开 相关的xml部分是: <directors> <item>Tom Tykwer</item> <item>Andy Wachowski</item> </directors> 给我 Tom Tykwer Andy Wachowski 这个命令直接在终端执行 xmlsta
<directors>
<item>Tom Tykwer</item>
<item>Andy Wachowski</item>
</directors>
给我
Tom Tykwer Andy Wachowski
这个命令直接在终端执行
xmlstarlet sel -t -v "imdbdocument/directors/item" mymovieapi.xml
给我:
(empty line)
Tom Tykwer
Andy Wachowski
Tom Tykwer
Andy Wachowski|
当我没有指定-n选项时,我不知道为什么要添加新行
我的一些搜索建议如下:
xmlstarlet sel -t -m "imdbdocument/directors" -v "item" -o "|" mymovieapi.xml
但这只是给了我:
Tom Tykwer
Andy Wachowski|
如果能得到任何帮助,我将不胜感激。我在Debian Wheezy上的xmlstarlet 1.3.1和Xubuntu 13.10上的xmlstarlet 1.5.0中看到了这种行为。您可以尝试
xmlstarlet sel -t -v "imdbdocument/directors/item" mymovieapi.xml | awk '1' ORS='|'
有输出
|Tom Tykwer|Andy Wachowski|
或者,如果您不需要引入和引出管道|
:
xmlstarlet sel -t -v "imdbdocument/directors/item" mymovieapi.xml | awk 'NF>0 {if (i++) printf "|"; printf "%s", $0 } END { printf "\n" }'
给予
仅使用xmlstarlet的解决方案:
xmlstarlet sel -T -t -v '/imdbdocument/directors/item[1]' -m '/imdbdocument/directors/item[position()>1]' -o '|' -v . mymovieapi.xml
我使用1.5版进行了测试,但我相信它也应该适用于早期版本
或者,使用
--if
代替2个XPath表达式:
xmlstarlet sel -T -t -m '/imdbdocument/directors/item' --if 'position() > 1' -o '|' -b -v . mymovieapi.xml
-b
是-break
,它结束当前语句(条件语句或循环语句),就像C中的}
。您应该使用-text
(或-T
),因为您不需要XML输出。我尝试了--text选项,但它对输出没有任何影响。谢谢,我确认这符合我的目的,并允许我继续。非常感谢。如果有只使用xmlstarlet的解决方案,我会很感兴趣。我的阅读表明这是可能的,但我的xmlstarlet版本似乎没有以同样的方式运行。非常感谢,这正是我想要的。我现在明白了,我的问题是不理解-m匹配和-v“.”语法。我假设您已将项目拆分为[1]和[position()>1],以便管道仅在项目之间打印,而不是在输出的开头或结尾。也可以使用--if
来获取项目之间的管道,就像在awk解决方案中一样。我采用第一种方法是因为在编写XPath时,我倾向于集中思考。
xmlstarlet sel -T -t -m '/imdbdocument/directors/item' --if 'position() > 1' -o '|' -b -v . mymovieapi.xml