Parsowanie XML i odczyt statusów

0

Z gory przepraszam jesli to banał. Probuje odczytac statusy.
Probowalem tak i siak i nic
wymodzilem cos takiego, ale nie działa. Help.

var
DOC:IXMLDocument;
  i, j: Integer;
  OrderChilds, properties_Node: IXMLNode;
  propChildList: IXMLNodeList;
odpowiedz : string;
begin
odpowiedz := '?xml version="1.0" encoding="UTF-8"?>
<trackandtrace>
<Parcel Weight="0.4" ClientRef="clientref" PclID="9989888">
<Statuses>
<Status StInfo="Valickova" Depo="62" StDate="2016-04-01 11:53:47" StCode="5"/>
<Status StInfo="10:00-13:00" Depo="62" StDate="2016-04-01 07:18:47" StCode="4"/>
<Status StInfo="" Depo="62" StDate="2016-03-31 18:04:50" StCode="7"/>
<Status StInfo="2016-04-01" Depo="62" StDate="2016-03-31 18:03:18" StCode="9"/>
<Status StInfo="" Depo="62" StDate="2016-03-31 11:40:50" StCode="12"/>
<Status StInfo="10:00-13:00" Depo="62" StDate="2016-03-31 07:09:04" StCode="4"/>
<Status StInfo="" Depo="62" StDate="2016-03-31 06:16:08" StCode="3"/>
<Status StInfo="codref" Depo="5" StDate="2016-03-31 00:49:00" StCode="1"/>
<Status StInfo="" Depo="47" StDate="2016-03-30 15:12:09" StCode="86"/>
<Status StInfo="" Depo="0" StDate="2016-03-30 10:37:14" StCode="52"/>
<Status StInfo="" Depo="0" StDate="2016-03-30 10:37:14" StCode="51"/>
</Statuses>
</Parcel>
</trackandtrace>';
doc := LoadXMLData(odpowiedz);
 doc.Active;

   for i := 0 to DOC.ChildNodes.Nodes['parcel'].ChildNodes.Count - 1 do
  begin
    OrderChilds := DOC.ChildNodes.Nodes['parcel'].ChildNodes[i];
    if OrderChilds.NodeName = 'Statuses' then
    begin
      properties_Node := OrderChilds.ChildNodes.Nodes['Status'];
      if Assigned(properties_Node) then begin
        propChildList := properties_Node.ChildNodes;
        for j := 0 to propChildList.Count - 1 do begin
          Memo1.Lines.Add(propChildList.Nodes[j].NodeValue);
        end;
      end;
    end;
  end;
end;
0

Ten Twój XML nie wygląda na poprawny.

0

Czyli pozostaje "reczna" obrobka?:)

0

Nie, po prostu to:

?xml version="1.0" encoding="UTF-8"?>
<trackandtrace>
<Parcel Weight="0.4" ClientRef="clientref" PclID="9989888">
<Statuses>
<Status StInfo="Valickova" Depo="62" StDate="2016-04-01 11:53:47" StCode="5"/>
<Status StInfo="10:00-13:00" Depo="62" StDate="2016-04-01 07:18:47" StCode="4"/>
<Status StInfo="" Depo="62" StDate="2016-03-31 18:04:50" StCode="7"/>
<Status StInfo="2016-04-01" Depo="62" StDate="2016-03-31 18:03:18" StCode="9"/>
<Status StInfo="" Depo="62" StDate="2016-03-31 11:40:50" StCode="12"/>
<Status StInfo="10:00-13:00" Depo="62" StDate="2016-03-31 07:09:04" StCode="4"/>
<Status StInfo="" Depo="62" StDate="2016-03-31 06:16:08" StCode="3"/>
<Status StInfo="codref" Depo="5" StDate="2016-03-31 00:49:00" StCode="1"/>
<Status StInfo="" Depo="47" StDate="2016-03-30 15:12:09" StCode="86"/>
<Status StInfo="" Depo="0" StDate="2016-03-30 10:37:14" StCode="52"/>
<Status StInfo="" Depo="0" StDate="2016-03-30 10:37:14" StCode="51"/>
</Statuses>
</Parcel>
</trackandtrace>

to nie jest plik XML i żaden parser go nie przyjmie. Brakuje < na samym początku pliku.

0

poprawilem ale nie w tym problem. To byl tylko blad przy wklejaniu postu. W programie bylo ok.

0

_

CO NIE DZIAŁA??????

0

tu mi wywala blad I/O error 105
for i := 0 to DOC.ChildNodes.Nodes['parcel'].ChildNodes.Count - 1 do

0

sformatuj sobie tego xmla jakoś po ludzku to zobaczysz, że ścieżka, którą podajesz ma się nijak do xmla - tam nie ma czegoś takiego jak DOC.ChildNodes.Nodes['parcel'].

0

No wlasnie tu brzmi pytanie. Jak mam zapytac (xml jest generowany przez api firmy i nic nie moge zmienic) aby dostac tablice z poszczegolnymi statusami.

4

Słuchaj, jeśli posiadasz gotowy XML i jesteś pewien, że w takiej formie zawsze będziesz go dostawał to w najprostszy sposób możesz sobie przygotować gotową klasę do jego obróbki używając xml data binding jest to wbudowane narzędzie delphi:

File->New->Other->XML->New XML Data Binding

Tam odpali Ci się kreator gdzie wybierasz plik xml i generuje Ci całego unita z odpowiednimi klasami do twojego XML. Nie jest to rozwiązanie idealne ale dla tak prostego XML jest to chyba najłatwiejszy sposób. Wtedy będziesz miał w programie np coś takiego NAZWAKLASYXML.trackandtrace.Parcel itd.
Dla np statuses będzie to typ bodajże TCollection więc będziesz mógł spokojnie pętle zrobić

for i: 0 to NAZWAKLASYXML.trackandtrace.Parcel.Statuses.Count do
begin
  //  NAZWAKLASYXML.trackandtrace.Parcel.Statuses[i];   //robisz z tym co chcesz
end;

pisałem z głowy ale mniej więcej powinno to smigać.

0

Bardzo dziękuję. Działa

1 użytkowników online, w tym zalogowanych: 0, gości: 1