正确的 XPath 将产生空结果
本文关键字:结果 XPath | 更新日期: 2023-09-27 18:34:25
我正在尝试根据节点的ID从html页面中选择一个节点。由于外部限制,我必须使用 XPath 来做到这一点。
我想获取论坛帖子的容器元素,在本例中为 Delphi-PRAXiS。我附上了该页面的简单示例。
我需要的节点是一个 id 为"posts"的div,所以我的查询会//div[@id='posts']
.问题是,结果是一个空列表。如果我使用//*[@id='posts']
查询,我会得到我的节点。
我使用框架的 XmlDocument 类尝试了这个。
最终我想使用 Html Agility Pack(使用与 XmlDocument 相同的 XPath 类(,但如果我使用它,无论查询字符串如何,我都不会得到任何结果。
我知道查询字符串是正确的,所以我的猜测是解析器有问题。但不知何故,我怀疑Microsoft会提供一个损坏的 XPath 解析器。
有什么建议吗?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="de">
<head>
<title>Some title</title>
</head>
<body>
<div>
<div class="page">
<div id="dp-page" class="round-all">
<div class="dpbox">
<div id="posts">
Here we go!
</div>
</div>
</div>
</div>
</div>
</body>
</html>
我发现了另一个线索:如果 xml 中存在节点<a name="poststop" id="poststop"></a>
,则查询失败,否则查询成功。但是为什么?
XHTML元素位于http://www.w3.org/1999/xhtml
命名空间中,因此您需要在选择器中指定它。您的代码应如下所示(在涉及命名空间的情况下,使用 XDocument
会更容易一些(。
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
var nodelist = doc.SelectNodes("//xhtml:div[@id='posts']", nsmgr);
虽然我不推荐它,但您也可以使用 XmlTextReader 加载没有命名空间的文档
// Create XML data element
xmlData = new XmlDocument();
// Read using XmlTextReader to strip namespaces
using (XmlTextReader tr = new XmlTextReader(sourceFile))
{
tr.Namespaces = false;
xmlData.Load(tr);
}
我将它用于一些文档处理,以确保在使用数据库配置数据搜索字段时无需担心命名空间。