使用xmlstarlet从xml文件中选择元素,不能完全正确地获得语法

时间:2010-06-28 18:50:51

标签: xmlstarlet

以下是xml片段:

$ cat short.xml 
<hostnames>
    <hostname name="yahoo.com" type="user"/>
    <hostname name="ir1.fp.vip.sp2.yahoo.com" type="PTR"/>
</hostnames>
<hostnames>
    <hostname name="Inc.com" type="user"/>
    <hostname name="www.inc.com" type="PTR"/>
</hostnames>

所需的输出是:

yahoo.com | ir1.fp.vip.sp2.yahoo.com
Inc.com | www.inc.com

到目前为止我只有部分工作:     $ xml sel -t -m“// hostname”-v“@name”-n short.xml

我似乎无法正确捕获Type =条件。 TIA。

3 个答案:

答案 0 :(得分:4)

仅使用xmlstarlet一次的另外两个解决方案(无需迭代):

xmlstr='
<root>
  <hostnames>
    <hostname name="yahoo.com" type="user"/>
    <hostname name="ir1.fp.vip.sp2.yahoo.com" type="PTR"/>
  </hostnames>
  <hostnames>
    <hostname name="Inc.com" type="user"/>
    <hostname name="www.inc.com" type="PTR"/>
  </hostnames>
</root>
'

echo "$xmlstr" | xmlstarlet sel -T -t -m "//hostnames" -m "hostname[@type='user']" -v '@name' -o " | " -b -m "hostname[@type='PTR']" -v '@name' -n

echo "$xmlstr" | xmlstarlet sel -T -t -m "//hostname" -i "@type='user'" -v '@name' -o " | " -b -i "@type='PTR'" -v '@name' -n

答案 1 :(得分:3)

您需要使用xmlstarlet el或其他内容计算主机名,然后使用以下内容进行迭代:

xmlstarlet sel -t -c "//hostnames[1]" short.xml | xmlstarlet sel -t -m "//hostname/@name" -v . -o ' | '

如果更好地设计XML,这将会容易得多。 :)

答案 2 :(得分:0)

有问题的例子是无效的xml。

xmlstarlet --version
1.3.1
compiled against libxml2 2.8.0, linked with 20800
compiled against libxslt 1.1.26, linked with 10126
xmlstarlet val -e short.xml 
short.xml:5.1: Extra content at the end of the document
<hostnames>
^
short.xml - invalid

使用mitm answer的想法是非常好的治疗方法。