Search code examples
xmlxpathxmlstarlet

Xpath for node with multipe attributes


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>Foo</groupId>
    <artifactId>Bar</artifactId>
    <version>9.9.9</version>
</project>

I am trying to edit the version value with xmlstarlet, however I am having trouble coming up with the XPath that points to that node since the parent node has multiple attributes I can't seem to get my way around it.

I tried the following, however I get Invalid expression errors:

xmlstarlet ed --omit-decl -L -u "/project[@xmlns=http://maven.apache.org/POM/4.0.0 and @xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance and @xsi:schemaLocation=http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd]/version" -v 10.10.10 ./file.xml

Solution

  • xmlns attributes are namespace definitions. The one without a colon defines the default namespace. XPath doesn't support default namespaces so you have to refer to it explicitly. Recent versions of XMLStarlet (1.5.0+) bind the default namespace to "_" so you can do this:

    xmlstarlet ed --omit-decl -L -u "/_:project/_:version" -v 10.10.10 ./file.xml
    

    You can bind namespaces explicitly like this:

    xmlstarlet ed -N pom=http://maven.apache.org/POM/4.0.0 --omit-decl -L -u "/pom:project/pom:version" -v 10.10.10 ./file.xml
    

    See also, Section 5.1 of the manual.