无法使用 XPath 从标签中提取所需的属性值
Not able to extract desired attribute value from a tag using XPath
我有一个如下所示的 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 表达式从 <p>
中提取 align
的属性值。所以,我尝试使用此代码:
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
,也不会提取任何内容。谁能告诉我我在这里做错了什么?对代码进行任何修改都会有所帮助。
您的 XHTML 中没有名为 p
的元素,即使它可能看起来如此。
当您在 XML 中使用 xmlns
属性时,您声明带有该属性的元素以及所有后代元素都在该命名空间中(除非被其他命名空间声明显式覆盖) .
因此,根元素未命名为 html
,它实际上是“http://www.w3.org/1999/xhtml" namespace.’ The html
part is called the “local part.” The local name and the namespace URI are collectively known as a QName.
中的‘html”
按照惯例,这是将命名空间URI放在大括号中作为前缀来编写的,因此为了便于讨论,根元素是{http://www.w3.org/1999/xhtml}html
,您要查找的元素是{http://www.w3.org/1999/xhtml}p
.
处理此问题的一种方法是 install a NamespaceContext,但由于我一直无法理解的原因,Java SE 没有 public NamespaceContext 的标准实现,这使得将其设置为琐事。
一种更简单的方法是定制您的 XPath 表达式以仅基于每个元素的局部部分搜索元素:
Inst.evaluate("//*[local-name()='p']/@align", doc, XPathConstants.NODESET);
如果您在创建 DocumentBuilder 之前使用 DocumentBuilderFactory, remember to call setNamespaceAware(true)。
我有一个如下所示的 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 表达式从 <p>
中提取 align
的属性值。所以,我尝试使用此代码:
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
,也不会提取任何内容。谁能告诉我我在这里做错了什么?对代码进行任何修改都会有所帮助。
您的 XHTML 中没有名为 p
的元素,即使它可能看起来如此。
当您在 XML 中使用 xmlns
属性时,您声明带有该属性的元素以及所有后代元素都在该命名空间中(除非被其他命名空间声明显式覆盖) .
因此,根元素未命名为 html
,它实际上是“http://www.w3.org/1999/xhtml" namespace.’ The html
part is called the “local part.” The local name and the namespace URI are collectively known as a QName.
按照惯例,这是将命名空间URI放在大括号中作为前缀来编写的,因此为了便于讨论,根元素是{http://www.w3.org/1999/xhtml}html
,您要查找的元素是{http://www.w3.org/1999/xhtml}p
.
处理此问题的一种方法是 install a NamespaceContext,但由于我一直无法理解的原因,Java SE 没有 public NamespaceContext 的标准实现,这使得将其设置为琐事。
一种更简单的方法是定制您的 XPath 表达式以仅基于每个元素的局部部分搜索元素:
Inst.evaluate("//*[local-name()='p']/@align", doc, XPathConstants.NODESET);
如果您在创建 DocumentBuilder 之前使用 DocumentBuilderFactory, remember to call setNamespaceAware(true)。