按名称空间属性选择的XPathExpression不会选择任何内容

时间:2015-09-11 12:26:04

标签: java xml xpath

我正在尝试从standalone.xml(Wildfly 9.0)中提取数据库凭据(链接到8.1版本)。使用XPath,我面临的问题是我的XPathExpression无法正常工作,

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());

线,

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

不从子系统元素中获取节点(NodeList count为0),

"/server"

工作正常(NodeList计数为7).Below是文件,

<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>

有人可以告诉我这里有什么问题吗?

1 个答案:

答案 0 :(得分:3)

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

此表达式针对属性xmlns进行测试,该属性不可能存在,因为它是被禁止的。该伪属性用于声明命名空间,与任何命名空间属性一样,包括xmlns:xsl等,您无法直接访问它们。

相反,请使用:

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

但除非默认命名空间已经urn:jboss:domain:datasources:3.0,否则这没有意义。

更好的方法

问题是:表达式将在无命名空间中查找subsystem,找不到任何内容,然后将永远不会使用谓词。

要解决此问题,请使用:

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

Or declare the namespace,例如前缀ds3,然后更简单,这可行:

/server/ds3:subsystem

虽然这会修复您的表达,却无法找到任何内容,因为subsystem不是server的孩子。使用:

/server/profile/ds3:subsystem