如何获取XMLLINT将--xpath结果作为数组放置

时间:2019-02-05 21:42:47

标签: xml bash xmllint

我希望将XMLLINT的输出放入BASH数组中。但是我所能得到的只是一个字符串。结果将返回许多匹配,没有匹配可用于解析返回的字符串的任何模式。

  • 我尝试了--format并将“>”重定向到文本文件。
  • 我已尝试对所有实例//和仅一个/进行xpath

mcv.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <instance>
        <absolutePath>/abc/def</absolutePath>
    </instance>
    <instance>
        <absolutePath>/abc/hij</absolutePath>
    </instance>
</root>

mcv.sh

#!/usr/bin/bash

declare -a wwArray=()

wwCount=$(xmllint --xpath 'count(//absolutePath)' "mcv.xml")

printf "wwCount: '%s' \n" ${wwCount}

i=1

while [ $i -le ${wwCount} ];
do
        wwExtracted=$(xmllint --xpath '//absolutePath['${i}']/text    ()' "mcv.xml")
        printf " - absolutePath: '%s' \n" ${wwExtracted}
        printf " - index: '%d' \n" ${i}
        let i=i+1
done 

运行此命令,输出为:

wwCount: '2'
 - absolutePath: '/abc/def/abc/hij'
 - index: '1'
XPath set is empty
 - absolutePath: ''
 - index: '2'

...我希望它是:

wwCount: '2'
 - absolutePath: '/abc/def'
 - index: '1'
 - absolutePath: '/abc/hij'
 - index: '2'

1 个答案:

答案 0 :(得分:1)

使现有代码正常工作所需的最小更改是在[$i]之前添加括号,如下所示:

#!/usr/bin/bash
wwCount=$(xmllint --xpath 'count(//absolutePath)' "mcv.xml")
for ((i=1; i<=wwCount; i++)); do
        wwExtracted=$(xmllint --xpath '(//absolutePath)['"$i"']/text()' "mcv.xml")
        printf " - absolutePath: '%s' \n" "$wwExtracted"
        printf " - index: '%d' \n" "$i"
done 

也就是说,这确实效率很低(一遍又一遍地运行XPath)。考虑从xmllint改用XMLStarlet,可以指示它在输出元素之间插入换行符,因此您可以告诉bash将这些项目直接加载到真实的shell数组中:

#!/usr/bin/bash
readarray -t items < <(xmlstarlet sel -t -m '//absolutePath' -v './text()' -n <mcv.xml)
printf ' - absolutePath: %s\n' "${items[@]}"

一旦将内容放入数组中(由上面的readarray创建),您还可以按索引进行迭代:

for idx in "${!items[@]}"; do
  printf ' - absolutePath: %s\n' "${items[$idx]}"
  printf ' - index: %s\n' "$idx"
done