如何使用xmllint和XPath从属性中获取值?

时间:2012-07-23 11:12:47

标签: xml shell xpath

我想获取name的值并使用XMLLint

将其放入变量中
<body>
<value name="abc"></value>
</body>

echo 'cat //body/value/@name' | xmllint --shell "test.xml"

/ >  -------
 name="abc"
/ > 

所以我想将值“abc”赋给变量$ test

3 个答案:

答案 0 :(得分:27)

您需要使用fn:string(),它会将其参数的值返回为xs:string。如果它的参数是一个属性,它将返回属性的值为xs:string

test=$(xmllint --xpath "string(//body/value/@name)" test.xml)

答案 1 :(得分:4)

我最近不得不将使用--xpath的原始简单解决方案移植到缺少此功能的平台,因此不得不采用&#34; cat&#34;解决方案呢。这将处理多个匹配,在Ubuntu 12.04和Solaris 11上进行测试:

getxml() { # $1 = xml file, $2 = xpath expression
    echo "cat $2" | xmllint --shell $1 |\
    sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1/gp'
}

e.g。从glassfish域配置中提取实例名称:

$ getxml /tmp/test.xml "//server[@node-ref]/@name"
inst1
inst2

sed后处理只是抓取所有引用的值,这些值足以满足我的需求(获得一些glassfish配置)。

答案 2 :(得分:4)

使用帮助awk命令的方法支持多个属性ego's approach的简化版本):

echo 'cat //*/@name' | xmllint --shell file | awk -F\" 'NR % 2 == 0 { print $2 }'

awk命令:

  • 通过xmllint字符将"的输出行拆分为字段。 (-F\"

    • 请注意xmllint将输出中属性值的引用规范化为"...",即使输入为'...',也足以按"进行拆分
  • 仅处理偶数行(NR %2 == 0),从而过滤掉cat总是打印的分隔线。

  • print $2然后仅打印第二个字段,即每个属性的,而不包含"..."

假设file中的以下示例XML:

<body>
  <value name="abc"></value>
  <value name="def"></value>
</body>

以上产量:

abc
def