I have the following XML sample file.
<root>
<ul id="nav">
<li id="id1">some</li>
<li id="id2"> unimportant
</li>
<li id="id3"> text.
</li>
</ul>
<ul id="tag">
<li id="id1">SOME</li>
<li id="id2"> MORE
</li>
<li id="id3"> TEXT.
</li>
</ul>
</root>
I would like to use xmllint
to extract all attribute values of all <li>
elements which are listed under <ul id="nav">
.
I can use
xmllint --xpath '//ul[@id="nav"]/li/@id' sample.xml
which will return
id="id1" id="id2" id="id3"
However, I would like to get
id1 id2 id3
I tried
xmllint --xpath 'string(//ul[@id="nav"]/li/@id)' sample.xml
but this only return the value of the first attribute
id1
Can I extract all values without resorting to other tools like awk, sed etc.? They may be delimited by either space or newline, it does not really matter in my case.
If you can use xmlstarlet, you can use the -v
(--value-of
) command line option:
xmlstarlet sel -t -v "//ul[@id='nav']/li/@id" sample.xml
I don't think you can use HTML as an input for the sel
command, but I could be wrong.
I know you can with the tr
(translate) command though (with --html
). Then you could use an XSLT...
xmlstarlet tr --html sample.xsl sample.xml
XSLT (sample.xsl)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:for-each select="//ul[@id='nav']/li/@id">
<xsl:value-of select="concat(.,'
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>