Finding elements with XPath in Delphi

爱⌒轻易说出口 提交于 2019-12-30 13:45:55

问题


I am trying to find an element in an XML document in Delphi. I have this code, but it always says 0 elements in the log:

function TForm1.KannaSidu: Boolean;
var
  Doc: IXMLDOMDocument; 
  List: IXMLDomNodeList;
begin
  try
    Doc := CreateOleObject('Microsoft.XMLDOM') as IXMLDomDocument;
    Doc.async:=False;
    Doc.load(Filename);
  except
    LogTx('Error on page');
  end;
  List:=Doc.selectNodes('/html/head');
  LogTx(IntToStr(List.length)+' elements');
  Result:=False;
end;

So how do I make XPath work?


回答1:


In the example code I find online for the selectNodes method, it is preceded by code that sets the document's SelectionNamespaces property via setProperty. Some even set SelectionLanguage, too.

Doc.setProperty('SelectionLanguage', 'XPath');
Doc.setProperty('SelectionNamespaces',
  'xmlns:xsl=''http://www.w3.org/1999/XSL/Transform''');

Based on the element names you're searching for, I guess you're processing an HTML file. The basic HTML elements are in the http://www.w3.org/1999/xhtml namespace, so try this:

Doc.setProperty('SelectionNamespaces',
  'xmlns:x=''http://www.w3.org/1999/xhtml''');
List := Doc.selectNodes('/x:html/x:head');

See also:

selectNodes does not give node list when xmlns is used on Microsoft's forum.




回答2:


If you're just trying to load a plain html file as xml, it would probably have multiple reasons to fail and choke on things like:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

You have to test that it actually loads correctly before doing anything else:

  if not Doc.load(filename) then
    raise Exception.Create('XML Loading error:' + Trim(Doc.parseError.reason));

It will give you the specific reason for the failure like this one:

XML Loading error:End tag 'head' does not match the start tag 'link'.



回答3:


IXMLDOMDocument.Load() does not raise an exception if something goes wrong with your file or with its content. Try the following to be sure there is nothing bad with it:

...
Doc.load(Filename);
if Doc.parseError.errorCode <> 0 then
  ShowMessage('Error : ' + + Doc.parseError.reason) 
else
  ShowMessage('No problem so far !');
...

I suck at XPath but maybe if html is your root node you don't need to include it in your query string, so try the following :

List:=Doc.selectNodes('//html/head');

or

List:=Doc.selectNodes('//head');



回答4:


Any possibility you need to escape the / ?



来源:https://stackoverflow.com/questions/1406138/finding-elements-with-xpath-in-delphi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!