Java XPath:具有默认命名空间xmlns的查询 [英] Java XPath: Queries with default namespace xmlns

查看:131
本文介绍了Java XPath:具有默认命名空间xmlns的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对此文件执行XPath查询(摘录显示):

 <?xml version =1.0 encoding =UTF-8?> 
<! - MetaDataAPI生成日期:2007年5月25日星期五下午3:26:31 CEST - >
< ModelClass xmlns =http://xml.sap.com/2002/10/metamodel/webdynproxmlns:IDX =urn:sap.com:WebDynpro.ModelClass:2.0>
< ModelClass.Parent>
< Core.Reference package =com.test.mypackagename =ModelNametype =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(结果);

我面临的问题是在XPath查询中引用默认命名空间时,不会调用getNamespaceURI方法来解析它。
此查询例如不提取任何内容:



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



现在我尝试通过用假前缀 d xmlns 来欺骗解析器c>然后相应地编写 getNamespaceURI 方法(以便返回 http://xml.sap.com/2002/10/metamodel/webdynpro 遇到 d 时。在这种情况下,调用 getNamespaceURI 但结果为XPath表达式评估始终是一个n空字符串。



如果我从文件和XPath查询表达式中删除名称空间,我可以得到我想要的字符串(com.test.mypackage)。 / p>

有没有办法让默认名称空间正常工作?

解决方案

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

  xpath.setNamespaceContext( new NamespaceContext(){
public String getNamespaceURI(String prefix){
switch(prefix){
casedf:returnhttp://xml.sap.com/2002/10 / metamodel / webdynpro;
...
}
});

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


I want to do an XPath query on this file (excerpt shown):

<?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"/>

This is a snippet of the code I'm using:

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

The problem I'm facing is that when the default namespace is referenced in an XPath query, the getNamespaceURI method is not called to resolve it. This query for example doesn't extract anything:

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

Now I've tried "tricking" the parser by replacing xmlns with a fake prefix d and then writing the getNamespaceURI method accordingly (so to return http://xml.sap.com/2002/10/metamodel/webdynpro when d is encountered). In this case, the getNamespaceURI is called but the result of the XPath expression evaluation is always an empty string.

If I strip out namespaces from the file and from the XPath query expression, I can get the string I wanted (com.test.mypackage).

Is there a way to make things work properly with the default namespace?

解决方案

In your Namespace context, bind a prefix of your choice (e.g. df) to the namespace URI in the document

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

and then use that prefix in your path expressions to qualify element names e.g. /df:ModelClass/df:ModelClass.Parent/df:Core.Reference[@type = 'Model']/@package.

这篇关于Java XPath:具有默认命名空间xmlns的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆