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

问题描述 投票:0回答:6

我想获取 name 的值并使用 XMLLint 将其放入变量中

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

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

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

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

xml shell xpath
6个回答
55
投票

您需要使用 fn:string(),它将返回其参数的值作为

xs:string
。如果它的参数是一个属性,它将返回该属性的值作为
xs:string

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

8
投票

试试这个,虽然不漂亮,但很有效:)

我只是从 stdout 中删除包含

>
的行,剪切字符串以获取
=
之后的第二部分,然后删除“

test=$(echo 'cat //body/value/@name' | xmllint --shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d \"); 
echo $test

6
投票

带有helper

awk
命令的方法,支持多个属性ego方法的简化版本):

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

awk
命令:

  • xmllint
    的输出行按
    "
    字符拆分为字段。 (
    -F\"
    )

    • 请注意,
      xmllint
      在输出时将属性值周围的引用标准化为
      "..."
      ,即使输入有
      '...'
      ,因此用
      "
      分割就足够了。
  • 仅处理偶数行 (

    NR %2 == 0
    ),从而过滤掉
    cat
    总是打印的分隔线。

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

假设

file
中有以下示例 XML:

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

以上产量:

abc
def

3
投票

我最近不得不使用 --xpath 将我原来的更简单的解决方案移植到缺乏此功能的平台,因此也必须采用“cat”解决方案。这将处理多个匹配,已在 Ubuntu 12.04 和 Solaris 11 上测试:

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

例如从 glassfish 域配置中提取实例名称:

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

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


2
投票

以匹配多行并提取其同名属性的值为目标,并以previous答案为基础,这对我有用,而且更短,呵呵

xmllint --xpath "//*/@value" file.xml | awk -F\" '{ print $2 }'

-1
投票

下一个对我有用:

xmllint --xpath '//o/@loc' file.xml | sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1\n/gp'
© www.soinside.com 2019 - 2024. All rights reserved.