假设我有:
$ cat file
<?xml version='1.0' encoding='UTF-8'?>
<msg date='2020-03-21' time='2021-04-27T11:33:27Z'
type='UNKNOWN' level='16' host_id='localhost'
host_addr='127.0.0.1' pid='6322'>
<txt>service_update * orclcdb = 0</txt>
</msg>
我想把//msg
下的所有属性都作为key=value
对。
有了ruby
,我可以做到:
ruby -r nokogiri -e '
doc=Nokogiri::XML($<.read)
doc.xpath("//msg/@*").each{ |e| puts "#{e.name}=#{e.value}" }
' file
获得:
date=2020-03-21
time=2021-04-27T11:33:27Z
type=UNKNOWN
level=16
host_id=localhost
host_addr=127.0.0.1
pid=6322
如果我想要所有的元素和属性,我可以:
ruby -r nokogiri -e '
doc=Nokogiri::XML($<.read)
doc.xpath("//msg/@* | //msg/*").each{ |e|
puts "#{e.name}=#{e.content}"}
' file
date=2020-03-21
time=2021-04-27T11:33:27Z
type=UNKNOWN
level=16
host_id=localhost
host_addr=127.0.0.1
pid=6322
txt=service_update * orclcdb = 0
我正在尝试在xmlstarlet
中复制此
我试过:
xmlstarlet sel -T -t -m "//msg/*" -v "concat(name(),'=',text())" -n file
但这只适用于标记,而不适用于属性。
如果使用text()
,它只引用文本节点的内容,对属性没有意义。
您需要使用.
,它是节点、属性或原子值的上下文项(或上下文项表达式(。
xmlstarlet sel -T -t -m "//msg/@*" -v "concat(name(),'=',.)" -n file
date=2020-03-21
time=2021-04-27T11:33:27Z
type=UNKNOWN
level=16
host_id=localhost
host_addr=127.0.0.1
pid=6322
或者,如果您同时想要节点和属性:
xmlstarlet sel -T -t -m "//msg/@* | //msg/*" -v "concat(name(),'=',.)" -n file
date=2020-03-21
time=2021-04-27T11:33:27Z
type=UNKNOWN
level=16
host_id=localhost
host_addr=127.0.0.1
pid=6322
txt=service_update * orclcdb = 0