3

I am trying to extract the database credentials from standalone.xml(Wildfly 9.0) (link to 8.1 version). Using XPath for this, I am facing the issue that my XPathExpression is not working correctly,

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(System.getProperty("jboss.server.config.dir") + "/standalone.xml");

XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("/server/subsystem[@xmlns='urn:jboss:domain:datasources:3.0']/text()");

NodeList nl = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);

System.out.println("NodeList count " + nl.getLength());

the line,

"/server/subsystem[@xmlns='urn:jboss:domain:datasources:3.0']/text()"

is not fetching the nodes from the subsystem element(NodeList count is 0),

"/server"

works fine(NodeList count is 7).Below is the file,

<server xmlns="urn:jboss:domain:3.0">
    <profile>            
        <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
        <subsystem xmlns="urn:jboss:domain:datasources:3.0">
            <datasources>
                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
                    <driver>h2</driver>
                    <security>
                        <user-name>sa</user-name>
                        <password>sa</password>
                    </security>
                </datasource>
            </datasources>
        </subsystem>
        <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
            <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
        </subsystem>
    </profile>
</server>

Can anyone please tell me what is the issue here?

Abel
  • 56,041
  • 24
  • 146
  • 247
Anss
  • 664
  • 2
  • 7
  • 23

1 Answers1

3
/server/subsystem[@xmlns='urn:jboss:domain:datasources:3.0']/text()

This expression is testing against an attribute xmlns, which cannot possibly exist, because it is forbidden. That pseudo-attribute is used to declare a namespace and like any namespace attribute, including xmlns:xsl and the like, you cannot access them directly.

Instead, use:

 /server/subsystem[namespace-uri()='urn:jboss:domain:datasources:3.0']/text()

But this doesn't make sense unless the default namespace is already urn:jboss:domain:datasources:3.0.


Better approach

The problem is: the expression will look for subsystem in no-namespace, finds nothing, and then the predicate will never be used.

To resolve this, use either:

/server/*
    [namespace-uri()='urn:jboss:domain:datasources:3.0']
    [local-name() = 'subsystem']

Or declare the namespace, for instance for the prefix ds3, and then, much, much simpler, this works:

/server/ds3:subsystem

While this fixes your expression, it won't find anything, because subsystem is not a child of server. Use:

/server/profile/ds3:subsystem
Community
  • 1
  • 1
Abel
  • 56,041
  • 24
  • 146
  • 247
  • `/server/profile/ds3:subsystem` didn't work, I used /server/profile/subsystem[4] and it worked just fine. Thanks a lot for clarifying the namespace issue. – Anss Sep 11 '15 at 13:18
  • @Anss, `ds3` only works if you set the namespace correctly (see link). If `subsystem[4]` worked, then you have four elements in the default XPath namespace, which is not the case for the document in your original question (only one such in that namespace). But glad you have a solution ;) – Abel Sep 11 '15 at 13:30
  • Oh I missed the link. – Anss Sep 11 '15 at 13:40