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

后端 未结 4 1408
小鲜肉
小鲜肉 2020-12-08 13:23

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





echo \'cat //body         


        
相关标签:
4条回答
  • 2020-12-08 14:05

    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:

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

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

    $ 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).

    0 讨论(0)
  • 2020-12-08 14:20

    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 "

    test=$(echo 'cat //body/value/@name' | xmllint --shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d \"); 
    echo $test
    
    0 讨论(0)
  • 2020-12-08 14:23

    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.

    test=$(xmllint --xpath "string(//body/value/@name)" test.xml)
    
    0 讨论(0)
  • 2020-12-08 14:26

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

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

    The awk command:

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

      • Note that xmllint normalizes 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 cat invariably prints.

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

    Assuming the following sample XML in file:

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

    the above yields:

    abc
    def
    
    0 讨论(0)
提交回复
热议问题