1

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?

  • 4
    What does the XML file look like? – Bruce McGee Sep 10 '09 at 16:00
  • @Gunnar: Bruce is right. Without seeing the XML you're using, it's impossible to provide the answer to your question. Without that info, your XPath expression looks perfect; of course, it may be 100% wrong for the XML you actually have. – Ken White Sep 10 '09 at 17:56
  • The XML contains much data. It is an XHTML document. I can see from the XML parse errors that it is malformed in several places. – Gunnar Vestergaard Sep 14 '09 at 07:09

3 Answers3

3

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.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • I don't think it is the reason here. Moreover setProperty only exists in IXMLDOMDocument2, not in IXMLDOMDocument. – Francesca Sep 10 '09 at 20:26
3

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'.
Francesca
  • 21,452
  • 4
  • 49
  • 90
1

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');
bluish
  • 26,356
  • 27
  • 122
  • 180
Fred
  • 1,607
  • 20
  • 33