我读过 XPath - how to select text并认为我有大致的想法。但是,与往常一样,XPath 会站起来,对我发出嘶嘶声,然后迅速跑去寻找最近的细菌滋生的小便池淹死。
我有一个 JPA orm.xml 文件。它看起来像这样:
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>test</schema>
<catalog>test</catalog>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
我认为,下面的 XPath 表达式应该从 <schema>
中选择文本。元素:
/entity-mappings/persistence-unit-metadata/persistence-unit-defaults/schema/text()
但是使用 Java 的 XPath 实现,它不会。
更具体地说,以下代码在最后一行失败(使用 JUnit 断言)。 text
的值变量是空字符串。
// Find the file: URL to the orm.xml I mentioned above.
final URL ormUrl = Thread.currentThread().getContextClassLoader().getResource("META-INF/orm.xml");
assertNotNull(ormUrl);
final XPathFactory xpf = XPathFactory.newInstance();
assertNotNull(xpf);
final XPath xpath = xpf.newXPath();
assertNotNull(xpath);
final XPathExpression expression = xpath.compile("/entity-mappings/persistence-unit-metadata/persistence-unit-defaults/schema/text()");
assertNotNull(expression);
final String text = expression.evaluate(new InputSource(ormUrl.openStream()));
assertEquals("test", text);
这似乎让人怀疑我一开始对 XPath 表达式的了解是多么少。四处乱窜,然后我想看看是否有一个简单的 "/"
会选择根元素。幸运的是,这返回了一个非 null
NodeList
,但是 NodeList
是空的。我真的不想追捕 Java XPath 支持的作者并将他们串起来,但不遵循这种做法会变得非常困难。
请帮我一劳永逸地解决 XPath 问题。谢谢。
最佳答案
问题是 XML 声明了一个默认命名空间
xmlns="http://java.sun.com/xml/ns/persistence/orm"
虽然在您的 XPath 表达式中您没有提供相应的命名空间上下文。参见 this link有关如何使用 namespace 上下文的详细信息。那里有很多细节,但总而言之,您必须编写自己的 javax.xml.namespace.NamespaceContext
实现。允许 XPath 处理器将 namespace 前缀映射到 URI。在您的情况下,您必须为 default 命名空间提供到适当 URI 的映射。
关于java - 从 orm.xml 的 <schema> 元素中选择文本的 XPath 表达式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5488260/