Konrad Höffner
Konrad Höffner

Reputation: 12207

How to get attribute values of multiple nodes in xpath with just xmllint?

I want to query the names of all the persons in the test.xml below.

<body>
<person name="abc"></person>
<person name="def"></person>
<person name="ghi"></person>
</body>

basic query

This has the problem of including "name", which I don't want.

$ xmllint --xpath '//body/person/@name' test.xml`
 name="abc"
 name="def"
 name="ghi"

string function

Using the string function, I only get one result.

$ xmllint --xpath 'string(//body/person/@name)' test.xml
abc

sed and grep

This works but looks needlessly complicated to me.

xmllint --xpath '//body/person/@name' test.xml | grep -o '"\([^"]*\)"' | sed 's|"||g'
abc
def
ghi

Question

Is it possible to get multiple values without the attribute name and without using another tool like grep?

Upvotes: 1

Views: 181

Answers (2)

many-sigsegv
many-sigsegv

Reputation: 68

I had the same issue and end up using an xslt instead of an xpath

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>
  <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="//body/person[@name]">
    <xsl:value-of select="@name"/>
    <xsl:text>&#xa;</xsl:text> <!-- line break -->
  </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Thor
Thor

Reputation: 47089

I don't know about xmllint, but xmlstarlet can do it:

xmlstarlet sel -t -v 'body/person/@name' test.xml

Output:

abc                                  
def
ghi

Upvotes: 1

Related Questions