Поиск элементов с помощью 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');