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

问题描述

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

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

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

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

现在我尝试通过将 xmlns 替换为假前缀 d 来欺骗"解析器,然后相应地编写 getNamespaceURI 方法(所以在遇到 d 时返回 http://xml.sap.com/2002/10/metamodel/webdynpro).在这种情况下,会调用 getNamespaceURI,但 XPath 表达式求值的结果始终是空字符串.

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.

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

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?

推荐答案

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

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";
        ...
       }
    });

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

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 进行查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 20:46