它如何在delphi中运行XPath?

时间:2014-10-13 14:51:38

标签: delphi xpath

这是我的xml文件(content.xml):

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head></head>
   <body>
      <h1>Lorem ipsum dolor sit amet</h1>
  </body>
</html>

这是我在Delphi(XE5)中的代码:

procedure TForm1.Button1Click(Sender: TObject);
var
 doc: IXMLDocument;
 Sel: IDOMNodeSelect;
 List : IDOMNodeList;
 query: String;
 begin
   content := TFile.ReadAllText('C:\temp\content.xml');
   doc := TXMLDocument.Create(Application);
   doc.LoadFromXML(content);
   doc.Active := True;
   query := '//descendant::html';
   Sel := doc.DOMDocument as IDomNodeSelect;
   List := Sel.selectNodes(query);
  // List.length is 0 !!!!
end;

List为空的问题,shoud包含四个元素:HTML,head,body,h1(即“html”标签及其所有子节点。根据http://www.w3schools.com/xpath/xpath_syntax.asp XPath语法,我尝试了以下选项:< / p>

//html/* 
/html
/html/*

它们都不适合我,所以此时我不知道查询是否正常或我的代码是否在另一点失败。

3 个答案:

答案 0 :(得分:3)

您似乎在Delphi中使用MSXML,因此您需要确保首先调用

doc.setProperty('SelectionLanguage', 'XPath')

然后设置

doc.setProperty('SelectionNamespaces', 'xmlns:xhtml="http://www.w3.org/1999/xhtml"')

最后你需要在你想要限定元素的任何地方使用那个前缀xhtml,例如

doc.selectNodes('//xhtml:h1')

选择所有h1元素。

答案 1 :(得分:0)

我建议不要在这种情况下使用TFile.ReadAllText()。让TXMLDocument直接加载文件,然后您就不必处理任何编码问题。

您可以删除doc.LoadFromXML()并设置doc.FileName属性:

procedure TForm1.Button1Click(Sender: TObject);
var
  doc: TXMLDocument;
  ...
begin
  doc := TXMLDocument.Create(Application);
  try
    doc.FileName := 'C:\temp\content.xml';
    doc.Active := True;
    ...
  finally
    doc.Free;
  end;
end;

或者您可以使用TXMLDocument函数替换LoadXMLDocument(),该函数将文件名作为输入:

procedure TForm1.Button1Click(Sender: TObject);
var
  doc: IXMLDocument;
  ...
begin
  doc := LoadXMLDocument('C:\temp\content.xml');
  ...
end;

无论哪种方式,您都可以像Martin Honnen所建议的那样处理XPath查询。

答案 2 :(得分:-1)

下班后,错误非常简单,内容&#34;变量必须是AnsiString NOT String。 XPath是对的,但不是变量。

那是错的

var
 content: String;// WRONG should be content: AnsiString;
 begin
  content := TFile.ReadAllText('C:\temp\content.xml');
  doc := TXMLDocument.Create(Application);
  doc.LoadFromXML(content);
  doc.Active := True;

 end;

我看错了地方:查询变量和XPath语法。