【问题标题】:XPathExpression selecting by namespace attribute selects nothing按名称空间属性选择的 XPathExpression 不选择任何内容
【发布时间】:2015-09-11 12:26:04
【问题描述】:

我正在尝试从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 计数为 0),

"/server"

工作正常(NodeList 计数为 7)。下面是文件,

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

谁能告诉我这里有什么问题?

【问题讨论】:

  • 请看minimal reproducible example。您的代码“sn-p”大小为 23kB (!),几乎没有 minimal。暂时修复;)
  • 我下次会小心的。

标签: java xml xpath


【解决方案1】:
/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

【讨论】:

  • /server/profile/ds3:subsystem 没用,我使用了 /server/profile/subsystem[4] 并且效果很好。非常感谢您澄清命名空间问题。
  • @Anss, ds3 仅在您正确设置命名空间时才有效(请参阅链接)。如果subsystem[4] 有效,那么默认 XPath 命名空间中有四个元素,而原始问题中的文档不是这种情况(该命名空间中只有一个元素)。但很高兴你有一个解决方案;)
  • 哦,我错过了链接。
猜你喜欢
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 2014-12-26
相关资源
最近更新 更多