简体   繁体   English

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

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

I want to get the value of name and put it in a variable using XMLLint我想获取名称的值并使用 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

You need to use fn:string() , which will return the value of its argument as xs:string . 您需要使用fn:string() ,它将返回其参数的值为xs:string In case its argument is an attribute, it will therefore return the attribute's value as xs:string . 如果它的参数是一个属性,它将返回属性的值为xs:string

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

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

An approach with a helper awk command that supports multiple attributes (a streamlined version of ego's approach ): 使用helper awk命令支持多个属性 的方法自我方法的简化版本):

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

The awk command: awk命令:

  • splits xmllint 's output lines into fields by " chars. ( -F\\" ) 通过" chars。(- xmllint -F\\" )将xmllint的输出行拆分为字段

    • Note that xmllint normalizes quoting around attribute values to "..." on output, even if the input had '...' , so it's sufficient to split by " . 请注意,即使输入具有'...'xmllint将输出上属性值的引用规范化为"..." ,因此它足以按"分割"
  • only processes even-numbered lines ( NR %2 == 0 ), thereby filtering out the separator lines that cat invariably prints. 仅处理偶数行( NR %2 == 0 ),从而滤除cat总是打印的分隔线。

  • print $2 then prints only the 2nd field, which is the value of each attribute without the enclosing "..." . print $2然后只打印第二个字段,这是每个属性的 ,没有封闭的"..."

Assuming the following sample XML in file : 假设file包含以下示例XML:

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

the above yields: 以上产量:

abc
def

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. 我最近不得不将使用--xpath的原始简单解决方案移植到缺少此功能的平台,因此不得不采用“cat”解决方案。 This will handle multiple matches, tested on Ubuntu 12.04 and Solaris 11: 这将处理在Ubuntu 12.04和Solaris 11上测试的多个匹配:

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

eg 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配置)。

为了匹配多行并提取其同名属性的值并建立在以前的答案的基础上,这对我有用,而且更短,呵呵

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

The next works for me:下一个对我有用:

xmllint --xpath '//o/@loc' file.xml | sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1\n/gp'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM