Java的XPath的:与默认命名空间的xmlns查询(Java XPath: Queries wi

2019-06-24 17:08发布

我想在这个文件(如图节选)做XPath查询:

<?xml version="1.0" encoding="UTF-8"?>
<!-- MetaDataAPI generated on: Friday, May 25, 2007 3:26:31 PM CEST -->
<ModelClass xmlns="http://xml.sap.com/2002/10/metamodel/webdynpro" xmlns:IDX="urn:sap.com:WebDynpro.ModelClass:2.0">
    <ModelClass.Parent>
        <Core.Reference package="com.test.mypackage" name="ModelName" type="Model"/>

这是我使用的代码片段:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document document = builder.parse(new File(testFile));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
...

String result = xpath.evaluate(xpathQueryString, document);
System.out.println(result);

我现在面临的问题是,当默认命名空间中的XPath查询中引用时,getNamespaceURI方法不叫解决。 该查询例如不提取任何东西:

//xmlns:ModelClass.Parent/xmlns:Core.Reference[@type=\"Model\"]/@package

现在,我已经尝试通过更换“欺骗”解析器xmlns用假前缀d ,然后写getNamespaceURI相应的方法(因此返回http://xml.sap.com/2002/10/metamodel/webdynprod遇到)。 在这种情况下, getNamespaceURI被调用,但XPath表达式求值的结果始终是一个空字符串。

如果我从文件,并从XPath查询表达式去掉命名空间,我能得到我想要的字符串(com.test.mypackage)。

有没有办法让事情默认命名空间正常工作?

Answer 1:

在您的Namespace下,你的选择(例如前缀绑定df )的命名空间URI在文档中

xpath.setNamespaceContext( new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
      switch (prefix) {
        case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro";
        ...
       }
    });

然后使用前缀在路径表达式来限定元素名称如/df:ModelClass/df:ModelClass.Parent/df:Core.Reference[@type = 'Model']/@package



Answer 2:

XPath 1.0规范要求,“没有前缀意味着没有命名空间”。 所以JAXP,这是专为XPath 1.0中,是非常正确的阻止你绑定了“零前缀”一些非空的命名空间。

XPath 2.0中允许你声明在你的XPath表达式不合格名称默认命名空间,但要利用这一点,你需要一个API(例如Saxon的s9api),其采用了这个特征的优势。



文章来源: Java XPath: Queries with default namespace xmlns