从orm.xml <schema>元素中选择文本的XPath表达式是什么?</schema>

时间:2011-03-30 15:14:07

标签: java xpath

我读过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。感谢。

1 个答案:

答案 0 :(得分:4)

问题是XML声明了一个默认命名空间

xmlns="http://java.sun.com/xml/ns/persistence/orm"

在XPath表达式中,您没有提供相应的命名空间上下文。有关如何使用命名空间上下文的详细信息,请参阅this link。那里有很多细节,但总的来说,你必须编写自己的javax.xml.namespace.NamespaceContext实现,它允许XPath处理器将名称空间前缀映射到URI。在您的情况下,您必须提供默认命名空间到适当URI的映射。