gpt4 book ai didi

java - 如何让命名空间与 XPath 一起使用?

转载 作者:行者123 更新时间:2023-11-30 06:21:22 26 4
gpt4 key购买 nike

对于给定的 XML 和 XPath,在线 XPath 测试器的工作方式与我下面的代码类似(不匹配任何内容):http://www.xpathtester.com/xpath

import java.io.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

class test {

public static void main(String[] args) throws Exception {

XPathExpression expr = XPathFactory.newInstance().newXPath().compile(
"/A[namespace-uri() = 'some-namespace']"); // This does not select anything, replacing A with * does

// This XPath selects as expected (in all parsers mentioned): /*[namespace-uri() = 'some-namespace']

String xml = "<A xmlns=\"some-namespace\"> </A>";

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

System.out.println("Number of nodes selected: " + nodes.getLength());

for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("Node name: " + nodes.item(i).getNodeName());
}
}
}

Link to Ideone

无论文档工厂是否支持命名空间,上面的代码都不会选择任何内容。

这符合 XPath 标准吗?或者实现上的细微差别?

This资源提到以下内容:

Indeed, when the XML document uses the default namespace, the XPath expression must use a prefix even though the target document does not.

为了验证这一点,我更改了 XPath 以包含如下前缀:/p:A[namespace-uri() = 'some-namespace'] 并添加了一个命名空间解析器,该解析器返回前缀 p< 的 URI some-namespace/em>,这有效


问题:

1) 有没有办法让没有前缀的 XPath 表达式在具有默认命名空间的文档上工作?

2) [第二个 XPath 测试器][3] 如何工作? (该测试仪不符合标准)

注意:在我的应用程序中,我无法控制收到的文档和 XPath。但两者都保证有效。

最佳答案

Freeformatter.com XPath 异常

对于您的示例 XML,

<root>
<A xmlns="some-namespace"> </A>
<A xmlns="some-namespace2"> </A>
</root>

这个 XPath,

//A

不应选择任何内容,但在 Freeformatter.com 上,它选择

<A xmlns="some-namespace2"> </A>

这是错误

因此,完全停止,不要使用Freeformatter.com。不要尝试解决这个问题 - 只是不要使用该服务,因为不能信任它以一致的方式评估 XPath。

<小时/>

一般的 XPath 命名空间

1) Is there a way of making XPath expressions without prefixes work on documents that have default namespaces?

你可以

  1. 通过 local-name() 击败命名空间 [不推荐]
  2. 通过 local-name()namespace-uri() 尊重命名空间 [可以,但是很详细],或者
  3. 通过托管语言库的各种机制定义命名空间前缀[首选,但因 XPath 托管系统而异]

有关更多详细信息,包括如何以多种不同托管语言定义命名空间前缀的示例,请参阅 How does XPath deal with XML namespaces?

<小时/>

对于给定的固定 XPath,选择可以忽略命名空间吗?

In my application, I cannot control the document and XPath that I receive (it is guaranteed to be valid). So I have to work with whatever XPath is sent to me. I'm guessing the answer to my question would be no then.?

如果您询问是否有办法让 //A 从上面的示例 XML 中选择一个节点,并且仍然符合 XPath,那么答案确实是.

关于java - 如何让命名空间与 XPath 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48094588/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com