Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Парсинг XML в Delphi7 / 9 сообщений из 9, страница 1 из 1
28.05.2019, 15:29
    #39819389
SilverShield
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
Коллеги, прошу помочь.

Есть XML документ такого вида:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
<?xml version="1.0" encoding="UTF-8"?>
<response>

<lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">1</int>
  <lst name="params">
    <str name="q">(caption:123)</str>
    <str name="wt">xml</str>
    <str name="_">1559038856394</str>
  </lst>
</lst>
<result name="response" numFound="2" start="0">
  <doc>
    <str name="path">C:\Windows\System32\notepad.exe</str>
    <int name="status">1</int>
    <date name="datetime">2019-03-19T22:10:59Z</date>
    <int name="new">0</int>
    <arr name="caption">
      <str>123 — Блокнот</str>
    </arr>
    <str name="caption_ru">123 — Блокнот</str>    
    <int name="type">1</int>
    <int name="cid">3</int>
    <long name="_version_">1634683078699909120</long></doc>
  <doc>
    <str name="path">C:\Windows\System32\notepad.exe</str>
    <int name="status">2</int>
    <date name="datetime">2019-03-19T22:11:00Z</date>
    <int name="new">0</int>
    <arr name="caption">
      <str>123 — Блокнот</str>
    </arr>
    <str name="caption_ru">123 — Блокнот</str>
    <int name="type">1</int>
    <int name="cid">3</int>
    <long name="_version_">1634683078714589184</long></doc>
</result>
</response>


Есть код на Delphi 7 который должен разобрать этот документ и поместить его в массив.
Использую IXMLDOMNodeList и IXMLDomNode.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
type
TSearchResStruct = record
    Name: string;
    Value: string;
  end;
  TResultData =  array of TSearchResStruct;
  TResultDataStruct = record
    Elem: TResultData;
  end;
  TSearchResultMass = array of TResultDataStruct;

function SearchStrRows(res: IXMLDomNode): TSearchResultMass;
var
  j, k: Integer;
  ResData, ChildNode, ValueNode : IXMLDomNode;
  XML: IXMLDOMNodeList;
begin  
      ResData := ^res;

      for j:= 0 to ResData.attributes.length - 1 do
        if ResData.attributes.item[j].nodeName = 'numFound' then
          CountRecord := ResData.attributes.item[j].nodeValue;

      XML := ResData.selectNodes('doc');
      for j := 0 to (XML.length) - 1 do
      begin
        setlength(Result, length(Result) + 1);
        ChildNode := XML.item[j].firstChild;

        while ChildNode <> NIL do
        begin

          for k := 0 to ChildNode.attributes.length - 1 do
          begin
            if ChildNode.attributes.item[0].nodeValue <> null then
            begin
              setlength(Result[high(Result)].Elem, length(Result[high(Result)].Elem) + 1);
              Result[high(Result)].Elem[high(Result[high(Result)].Elem)].Name := ChildNode.attributes.item[0].nodeValue;
            end;
          end;

          ValueNode := ChildNode.firstChild;

          while ValueNode <> NIL do
          begin
            if ValueNode.nodeValue <> null then
              Result[high(Result)].Elem[high(Result[high(Result)].Elem)].Value := ValueNode.nodeValue;

            ValueNode := ValueNode.nextSibling;
          end;

          ChildNode := ChildNode.nextSibling;
        end;
      end;
    end
    else
      setlength(Result, 0);
end;



Пока структура XML была линейная все работало, но сломалось, когда появился элемент:
<arr name="caption">
<str>123 — Блокнот</str>
</arr>

в ValueNode := ChildNode.firstChild; возвращается null

Не могу сообразить как доработать схему на случай массива в одном из элементов. К имени элемента привязываться нельзя, к порядковому номеру тоже. И надо именно на Delphi7, такие ограничения (

Буду очень благодарен за помощь
...
Рейтинг: 0 / 0
28.05.2019, 16:04
    #39819411
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
SilverShield,

А что в итоге нужно найти?
...
Рейтинг: 0 / 0
28.05.2019, 18:03
    #39819457
SilverShield
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
В итоге мне надо распарсенные значения в массив поместить.

1. имя элемента
2. значение.

например,
имя: path
значение: C:\Windows\System32\notepad.exe

имя: caption
значение: 123 — Блокнот

а на элементе массиве текущая схема ломается
...
Рейтинг: 0 / 0
28.05.2019, 18:12
    #39819459
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
Поищи такие ключевые слова в гугле: Delphi XML XPath
Может наступит просветление, что делать с XML-ами
...
Рейтинг: 0 / 0
28.05.2019, 19:18
    #39819463
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
SilverShieldимя: caption
значение: 123 — БлокнотА здесь
Код: xml
1.
2.
3.
<arr name="caption">
  <str>123 — Блокнот</str>
</arr>

что должно получиться?
...
Рейтинг: 0 / 0
30.05.2019, 11:56
    #39820271
SilverShield
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
_Vasilisk_SilverShieldимя: caption
значение: 123 — БлокнотА здесь
Код: xml
1.
2.
3.
<arr name="caption">
  <str>123 — Блокнот</str>
</arr>

что должно получиться?

здесь надо пробежаться по массиву и из него все значения в строку загнать, например с разделителем "; "
...
Рейтинг: 0 / 0
30.05.2019, 13:43
    #39820308
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
SilverShield
Код: pascal
1.
ResData := ^res;


а что за синтаксис такой? это точно Delphi 7?
...
Рейтинг: 0 / 0
30.05.2019, 15:30
    #39820359
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
function SearchStrRows(const res: IXMLDomNode): TSearchResultMass;
var
  Docs: IXMLDOMNodeList;
  Childs: IXMLDOMNodeList;
  Child: IXMLDOMNode;
  i, j: Integer;
  Items: IXMLDOMNodeList;
  Idx: Integer;
begin
  Docs := res.selectNodes('doc');
  SetLength(Result, Docs.length);
  for i := 0 to Docs.length - 1 do begin
    Childs := Docs.item[i].childNodes;
    SetLength(Result[i].Elem, Childs.length);
    for j := 0 to Childs.length - 1 do begin
      Child := Childs.item[j];
      Result[i].Elem[j].Name := Child.attributes.getNamedItem('name').nodeValue;
      if Child.nodeName <> 'arr' then
        Result[i].Elem[j].Value := Child.text
      else begin
        Items := Child.childNodes;
        Result[i].Elem[j].Value := '';
        for Idx := 0 to Items.length - 1 do
          Result[i].Elem[j].Value := Result[i].Elem[j].Value + Items.item[idx].text + ';';
        if Result[i].Elem[j].Value <> '' then
          SetLength(Result[i].Elem[j].Value, Length(Result[i].Elem[j].Value) - 1);
      end;
    end;
  end;
end;

...
Рейтинг: 0 / 0
05.06.2019, 20:18
    #39823087
SilverShield
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг XML в Delphi7
Благодарю!
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Парсинг XML в Delphi7 / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]