Поиск элементов с помощью XPath в Delphi

Я пытаюсь найти элемент в документе XML в Delphi. У меня есть этот код, но он всегда говорит 0 элементов в журнале:

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;

Так как же заставить XPath работать?

4 ответа

Если вы просто пытаетесь загрузить обычный html-файл в формате xml, у него, вероятно, будет несколько причин сбоить и задушить такие вещи, как:

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

Вы должны проверить, что он действительно загружается правильно, прежде чем делать что-либо еще:

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

Это даст вам конкретную причину сбоя, как этот:

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

В примере кода я нахожу онлайн для selectNodes метод, ему предшествует код, который устанавливает документ SelectionNamespaces собственность через setProperty, Некоторые даже установлены SelectionLanguage, тоже.

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

Основываясь на именах элементов, которые вы ищете, я думаю, вы обрабатываете HTML-файл. Основные элементы HTML находятся в http://www.w3.org/1999/xhtml/, поэтому попробуйте это:

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

Смотрите также:

selectNodes не дает список узлов, когда xmlns используется на форуме Microsoft.

IXMLDOMDocument.Load() не вызывает исключение, если что-то идет не так с вашим файлом или его содержимым. Попробуйте следующее, чтобы убедиться, что в этом нет ничего плохого:

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

Я сосу на XPath, но, возможно, если html Ваш корневой узел вам не нужно включать в строку запроса, поэтому попробуйте следующее:

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

или же

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

Любая возможность вам нужно избежать /?

Другие вопросы по тегам