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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11611385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:36:39  来源:igfitidea点击:

How can I get the value from an attribute using xmllint and XPath?

xmlshellxpath

提问by Tran Ngu Dang

I want to get the value of name and put it in a variable using XMLLint

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

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

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

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

So I want to assign the value "abc" to variable $test

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

回答by h0li0

You need to use fn:string(), which will return the value of its argument as xs:string. In case its argument is an attribute, it will therefore return the attribute's value as xs:string.

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

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

回答by ego

Try this, it's not beautiful but it works :)

试试这个,它不漂亮,但它有效:)

I just erase lines containing >from stdout , cut the string to get the second part after the =, and delete "

我只是擦除包含>stdout 的行,剪切字符串以获取 之后的第二部分=,然后删除“

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

回答by mklement0

An approach with a helper awkcommandthat supports multiple attributes(a streamlined version of ego's approach):

带有支持多个属性辅助awk命令的方法ego 方法的简化版本):

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

The awkcommand:

awk命令:

  • splits xmllint's output lines into fields by "chars. (-F\")

    • Note that xmllintnormalizes quoting around attribute values to "..."on output, even if the input had '...', so it's sufficient to split by ".
  • only processes even-numbered lines (NR %2 == 0), thereby filtering out the separator lines that catinvariably prints.

  • print $2then prints only the 2nd field, which is the valueof each attribute without the enclosing "...".

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

    • 请注意,即使输入具有,也xmllint将围绕属性值的引用标准化为"..."on 输出'...',因此按 分割就足够了"
  • 只处理偶数行 ( NR %2 == 0),从而过滤掉cat总是打印的分隔线。

  • print $2然后只打印第二个字段,它是每个属性的,没有封闭的"...".

Assuming the following sample XML in file:

假设在以下示例 XML 中file

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

the above yields:

以上产量:

abc
def

回答by steve.sims

I recently had to port my original simpler solution using --xpath to a platform lacking this feature, so had to adopt the "cat" solution too. This will handle multiple matches, tested on Ubuntu 12.04 and Solaris 11:

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

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

e.g. extracting instance names from a glassfish domain config:

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

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

The sed post-processing just grabs all quoted values which was adequate for my needs (getting bits of glassfish config).

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