问题
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