无法使用 XPath 从标签中提取所需的属性值

Not able to extract desired attribute value from a tag using XPath

提问人:A Beginner 提问时间:11/3/2018 最后编辑:A Beginner 更新时间:11/3/2018 访问量:38

问:

我有一个XHTML,如下所示:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="sample" content="Just for sample"/>
    <title/>
  </head>
  <body>
    <h1>Sample Heading</h1>
    <p align="left">XHTML and HTML are relatives.<a href="http://www.google.com">Google</a>
    </p>
  </body>
</html>

我想从 Java 中使用 XPath 表达式中提取属性值。所以,我尝试使用这段代码:align<p>

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);


DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse("TestFile.xhtml");

//Create XPath

XPathFactory xpathfactory = XPathFactory.newInstance();
XPath Inst= xpathfactory.newXPath();
NodeList nodes = (NodeList)Inst.evaluate("//p/@align",doc,XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); ++i) 
   {
            Element e = (Element) nodes.item(i);
            System.out.println(e);
    }

在 Java 代码中。但我没有得到任何输出。即使我只写,也没有任何提取。谁能告诉我我在这里做错了什么?代码中的任何编辑都会有所帮助。//body

java XPath XHTML

评论


答:

0赞 VGR 11/3/2018 #1

XHTML 中没有命名的元素,即使它可能看起来是这样。p

在 XML 中使用该属性时,声明具有该属性的元素以及所有后代元素都位于该命名空间中(除非被其他命名空间声明显式覆盖)。xmlns

因此,根元素没有被命名,它实际上是“http://www.w3.org/1999/xhtml”命名空间中的html”。该部件称为“本地部件”。本地名称和命名空间 URI 统称为 QNamehtmlhtml

按照惯例,这是通过将命名空间 URI 放在大括号中作为前缀来编写的,因此为了便于讨论,根元素是 ,而您要查找的元素是 。{http://www.w3.org/1999/xhtml}html{http://www.w3.org/1999/xhtml}p

处理此问题的一种方法是安装一个 NamespaceContext,但由于我仍然无法理解的原因,Java SE 没有 NamespaceContext 的公共标准实现,这使得设置它成为一件苦差事。

一种更简单的方法是定制 XPath 表达式,以便仅根据每个元素的局部部分搜索元素:

Inst.evaluate("//*[local-name()='p']/@align", doc, XPathConstants.NODESET);

如果您使用的是 DocumentBuilderFactory,请记住在创建 DocumentBuilder 之前对其调用 setNamespaceAware(true)。

评论

0赞 A Beginner 11/3/2018
事实上,我已经使用并设置了.我已经编辑了我的问题以提供更多代码片段。所以,你的意思是即使你设置为true,我仍然需要添加?DocumentBuilderFactorysetNamepaceAware(true)setNamespaceAware[local-name()='p']
0赞 VGR 11/3/2018
是的。 单独将查找本地部分为“p”且命名空间 URI 为空的元素。p
0赞 A Beginner 11/3/2018
好的,这就是我的主要问题的答案。谢谢!我会将答案标记为已接受。