Java XPath:具有默认命名空间xmlns的查询

Pie*_* M. 7 java xml xpath namespaces xml-namespaces

我想对这个文件做一个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"/>
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的代码的片段:

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);
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,当在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).

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

Mic*_*Kay 12

XPath 1.0规范要求"没有前缀意味着没有命名空间".因此,为XPath 1.0设计的JAXP非常适合阻止您将"null前缀"绑定到某些非null命名空间.

XPath 2.0允许您为XPath表达式中的非限定名称声明默认命名空间,但是为了利用这一点,您将需要一个利用此功能的API(例如Saxon的s9api).


Mar*_*nen 9

在您的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";
        ...
       }
    });
Run Code Online (Sandbox Code Playgroud)

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

  • 在使用命名空间之前,请确保您还创建了一个名为命名空间的DocumentBuilder http://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setNamespaceAware%28boolean%29. (5认同)