5

The Maven settings file looks like:

<settings
    xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
    https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <servers>
        <server>
            <id>fake31</id>
            <username>username1</username>
            <password>bb</password>
        </server>
        <server>
            <id>fake</id>
            <username>username2</username>
            <password>aa2</password>
        </server>
        <server>
            <id>fake3</id>
            <username>username3</username>
            <password>aa3</password>
        </server>
    </servers>
    <mirrors>
    [parially cut]
    </mirrors>
</settings>

I have to - using xmlstarlet (?) - return a value of the username element for the id = fake.

I analyzed many examples and did countless tries but I failed.

When I use /settings/servers/server[id='fake']/username at https://www.freeformatter.com/xpath-tester.html, the result is what I expect.

Can someone help me? Thank you in advance.

Destroy666
  • 12,350

1 Answers1

6

The apparently obvious solution won't work, because there is no reference to the xmlns namespaces you're using. (Well, technically it will work but it'll not find anything. This used to bite me too.)

xmlstarlet sel -t -m '//server[id="fake"]' -v 'username' -n xmlfile

Instead you need either to specify the namespaces explicitly with -N or use the default namespace placeholder, _:

xmlstarlet sel -N mvn="http://maven.apache.org/SETTINGS/1.0.0" -t -m '//mvn:server[mvn:id="fake"]' -v 'mvn:username' -n xmlfile

xmlstarlet sel -t -m '//:server[:id="fake"]' -v '_:username' -n xmlfile

Mostly I prefer using the default placeholder. Either way, output for your example,

username2

For others reading this answer I should probably point out that although I've used the much shorter //server in my examples, your XPath //settings/servers/server is also (almost) correct and provides a tighter target to the relevant element

xmlstarlet sel -t -m '//_:settings/_:servers/_:server[_:id="fake"]' -v '_:username' -n xmlfile
Chris Davies
  • 4,560