Пасмурный Ослик ([info]zlobniy_her) wrote in [info]ru_delphi,
Уважаемые мастера, прошу вашей помощи. Имеется вот такой XML-файл, из него надо извлечь данные, находящиеся в тегах name и value:

<?xml version="1.0" ?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>news_id</name>
<value>
<string>4</string>
</value>
</member>
<member>
<name>date</name>
<value>
<dateTime.iso8601>20020627T04:45:50</dateTime.iso8601>
</value>
</member>
<member>
<name>title</name>
<value>
<string>More Standards for Web Services!</string>
</value>
</member>
<member>
<name>full_desc</name>
<value>
<string>WSDL is dead! Long live WSCI! Yep - it's another standard this time at the description layer.

Seems IBM and Microsoft have been ganging up on Sun, as far as the development of web services goes.

It's all here: http://www.theregister.co.uk/content/23/25914.html

All we need now is Oracle to release a few standards to interface to their database via a web service...</string>
</value>
</member>
<member>
<name>author</name>
<value>
<string>ComputerWire</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>

Я делаю так (использую TXMLDocument):

XMLDoc.XML.Add(S);
XMLDoc.Active:= true;
root := XMLDoc.DocumentElement;
S:= root.ChildNodes.Nodes['params'].ChildNodes.Nodes['param'].ChildNodes.Nodes['value'].ChildNodes.Nodes['struct'].ChildNodes.Nodes['member'].ChildNodes.Nodes['name'].Text;
ShowMessage(S);
S:= root.ChildNodes.Nodes['params'].ChildNodes.Nodes['param'].ChildNodes.Nodes['value'].ChildNodes.Nodes['struct'].ChildNodes.Nodes['member'].ChildNodes.Nodes['value'].ChildNodes.Nodes['string'].Text;
ShowMessage(S);

Но тут возникает у меня вопрос: как считать следующие данные, которые находятся в следующем теге <member> и как быть, если в <value></value> стоит не <string> </string> (<value><string>ComputerWire</string></value>), а <dateTime.iso8601></dateTime.iso8601> (<value><dateTime.iso8601>20020627T04:45:50</dateTime.iso8601></value>)?
Возможно, я делаю неправильно, просто с XML не работал никогда.
Заранее спасибо за советы.

  • Post a new comment

    Error

  • 4 comments

[info]uhsu

July 26 2005, 16:59:08 UTC 6 years ago

Используй XPath...

...тогда тебе не надо будет мучаться с этими километровыми "...ChildNodes.Nodes['XXX']...".
Про сам XPath можно почитать тут - http://www.raleigh.ru/XML/w3schools/xpath/

Как это реализовать:
1. Для начала импортируй библиотек типов MSXML в Delphi, как указано в http://xmlhack.ru/books/xslt/ch_09_02.html
2. Далее привожу кусок кода (например, на нажатие кнопы):

procedure TForm1.Button1Click(Sender: TObject);
var
  xmlDoc: IXMLDOMDocument2;
  nList: IXMLDOMNodeList;
  i: Integer;
  Str: String;

begin
  // Создаем новый документ
  xmlDoc := CoFreeThreadedDOMDocument.Create;
  // Загружаем данные из файла
  xmlDoc.load(ExtractFilePath(ParamStr(0)) + 'test.xml');
  // или, если из строки:
  // xmlDoc.loadXML(S);

  // Проверяем на валидность документа
  if(xmlDoc.parseError.errorCode <> 0) then
    begin
      // Если документ невалиден, выдаем сообщение об ошибке
      // и покидаем процедуру
      ShowMessage('Parse error!' + #13#10 +
                  'Error message: ' + xmlDoc.parseError.reason);
      Exit;
    end;

  // Получаем каждый нод member
  nList := xmlDoc.selectNodes('//member');
  // Если member'ов нет, выходим
  if(nList.length < 0) then
    Exit;

  // Поочередно обрабатываем каждый нод member
  for i:=0 to nList.length - 1 do
    begin
      Str := '';

      // Получаем значение из нода name
      // С атрибутами можно и через
      // nList.item[i].attributes.getNamedItem('name').text
      if(nList.item[i].selectNodes('./name').length > 0)  then
        Str := Str + nList.item[i].selectSingleNode('./name').text + #13#10;

      // Нод string в ноде value? Если да, то получаем его значение...
      if(nList.item[i].selectNodes('./value/string').length > 0)  then
        Str := Str + nList.item[i].selectSingleNode('./value/string').text +
                     #13#10;

      // Нод dateTime.iso8601 в ноде value? Если да, то получаем его значение...
      if(nList.item[i].selectNodes('./value/dateTime.iso8601').length > 0)  then
        Str := Str + nList.item[i].selectSingleNode('./value/dateTime.iso8601').text +
                     #13#10;

      ShowMessage(Str);
    end;

  xmlDoc := nil;
end;


Будут вопросы, стучись в асю 140060168.
Удачи!

[info]zlobniy_her

July 27 2005, 01:24:48 UTC 6 years ago

Re: Используй XPath...

ООООООООООООО!!!!
Спасибо!!!

[info]uhsu

July 26 2005, 17:12:11 UTC 6 years ago

Да, еще вот по XPath'у:
http://www.raleigh.ru/XML/XPathTutorial/
http://www.citforum.ru/internet/xpath/index.shtml

[info]zlobniy_her

July 27 2005, 01:25:39 UTC 6 years ago

Уже читаю :)
Спасибо!
Create an Account
Forgot your login or password?
Facebook Twitter More login options
English • Español • Deutsch • Русский…