2

我正在尝试根据节点的 id 从 html 页面中选择一个节点。由于外部限制,我必须使用 XPath 来做到这一点。

我想获取论坛帖子的容器元素,在这种情况下是 Delphi-PRAXiS。我附上了一个简单的页面示例。

我需要的节点是一个 id 为“posts”的 div,所以我的查询是//div[@id='posts']. 问题是,结果是一个空列表。如果我查询使用//*[@id='posts']我得到我的节点。

我使用框架的 XmlDocument 类进行了尝试。

最终我想使用Html Agility Pack(它使用与 XmlDocument 相同的 XPath 类),但如果我使用它,无论查询字符串如何,我都不会得到任何结果。

我知道查询字符串是正确的,所以我的猜测是解析器有问题。但不知何故,我怀疑微软会发布一个损坏的 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>

我发现了另一个线索:如果节点<a name="poststop" id="poststop"></a>存在于 xml 中,则查询失败,否则查询成功。但为什么?

4

2 回答 2

3

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);
于 2012-05-16T13:07:55.587 回答
0

虽然我不推荐它,但您也可以使用 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);
}

我将其用于一些文档处理,以确保在使用数据库配置数据搜索字段时无需担心命名空间。

于 2012-05-16T13:12:05.283 回答