PDA

View Full Version : XML Parsen / Behandeln der Feldinhalte der mehrfach vorkommenden Elemente



Seiten : [1] 2

fdh
25-11-19, 08:30
Hallo,

ich lese das XML nun ein.
Allerdings habe ich das Problem, die mehrfach vorkommenden Artikelnummern anzusprechen,
bzw. mir diese Felder in meine Dateifelder zu befördern. Als Tabellenfelder will das der Compiler nicht. Wie ist die Syntax?

EVAL orders
ORDERS.HEAD.ORDERNUMBER = '1TJW5S 2 '
ORDERS.HEAD.VERSIONNUMBER.VERSIONNAME = 'XML.EANCOM.MBO'
ORDERS.HEAD.VERSIONNUMBER.VERSIONNO = '8.1 '
ORDERS.HEAD.LINE.LINEITEMNUMBER(1) = '1 '
ORDERS.HEAD.LINE.PRODUCTNUMBER(1) = 'E1527875LG'
ORDERS.HEAD.LINE.LINEITEMNUMBER(2) = '2 '
ORDERS.HEAD.LINE.PRODUCTNUMBER(2) = 'N1527875RL'
ORDERS.HEAD.LINE.LINEITEMNUMBER(3) = ' '
ORDERS.HEAD.LINE.PRODUCTNUMBER(3) = ' '
ORDERS.HEAD.LINE.LINEITEMNUMBER(4) = ' '
ORDERS.HEAD.LINE.PRODUCTNUMBER(4) = ' '
ORDERS.HEAD.LINE.LINEITEMNUMBER(5) = ' '
ORDERS.HEAD.LINE.PRODUCTNUMBER(5) = ' '

//eval f41 = ORDERS.HEAD.LINE.LINEITEMNUMBER.Cnt_Line;
//eval f42 = ORDERS.HEAD.LINE.LINEITEMNUMBER.Cnt_Line;
//eval f41 = ORDERS.HEAD.LINE.LINEITEMNUMBER(Cnt_Line);
//eval f42 = ORDERS.HEAD.LINE.LINEITEMNUMBER(2 );
//eval f42 = ORDERS.HEAD.LINE.LINEITEMNUMBER(002.);

dLine_t ds template
d LineItemNumber...
d 3a
d ProductNumber...
d 10a

dhead_t ds qualified inz
d OrderNumber 10a
d VersionNumber likeDS(VersionNumber_t)
d Line likeDS(Line_t) Dim(05)
d Cnt_Line 3 0

Dankeschön.

Gruß
Franco

Fuerchau
25-11-19, 08:34
Der Debugger löst das etwas anders auf.
Für den Compiler ist der ArrayIndex dann anzugeben, wenn man ein DIM(nn) defineirt hat.

head_t. Line(n).LineItemNumber

Funktioniert natürlich nur, wenn du das Template auch qualified machst:

d Line_t ds template qualified

fdh
25-11-19, 09:31
Danke für die rasche Antwort.
Hat aber leider noch nicht funktioniert

dLine_t ds template qualified
d LineItemNumber...
d 3a
d ProductNumber...
d 10a

dhead_t ds qualified inz
d OrderNumber 10a
d VersionNumber likeDS(VersionNumber_t)
d Line likeDS(Line_t) Dim(05)
d Cnt_Line 3 0

dorders ds qualified inz
d head LikeDS(head_t)

EVAL orders ORDERS.HEAD.ORDERNUMBER = '1TJW5S 2 '
ORDERS.HEAD.VERSIONNUMBER.VERSIONNAME = 'XML.EANCOM.MBO'
ORDERS.HEAD.VERSIONNUMBER.VERSIONNO = '8.1 '
ORDERS.HEAD.LINE.LINEITEMNUMBER(1) = '1 '
ORDERS.HEAD.LINE.PRODUCTNUMBER(1) = 'E1527875LG'
ORDERS.HEAD.LINE.LINEITEMNUMBER(2) = '2 '
ORDERS.HEAD.LINE.PRODUCTNUMBER(2) = 'N1527875RL'
ORDERS.HEAD.LINE.LINEITEMNUMBER(3) = ' '
ORDERS.HEAD.LINE.PRODUCTNUMBER(3) = ' '
ORDERS.HEAD.LINE.LINEITEMNUMBER(4) = ' '

eval f41 = head_t.Line(1).LineItemNumber;
eval f42 = head_t.Line(2).LineItemNumber;

EVAL head_t.Line(1)
HEAD_T.LINE.LINEITEMNUMBER(1) = ' '
HEAD_T.LINE.PRODUCTNUMBER(1) = ' '

Gruß
Franco

B.Hauser
25-11-19, 10:09
Wie sieht denn das zugehörige XML-INTO Statement aus?

Birgitta

fdh
25-11-19, 10:19
Guten Morgen,

/free
options = 'doc=file case=any allowmissing=yes allowextra=yes ' +
'countprefix=cnt_ datasubf=data ';
Filename = '/XMLOrderIN/20191031_221735_1TJW5S_2.xml';
xml-into orders %xml(%Trim(Filename):options);
... ... ...

Gruß
Franco

fdh
26-11-19, 06:34
Guten Morgen,
gibt es im Forum vielleicht noch eine Idee?
Franco

Rainer Ross
26-11-19, 11:39
Hallo Franko,

anbei die Lösung für das Problem



ctl-opt dftactgrp(*no);
//------------------------------------------------------------------//
// //
// Parsen XML-DATEN - CCSID DER XML-DATEI MUSS 1208 SEIN //
// //
//----------------- //
// R.Ross 11.2019 * //
//------------------------------------------------------------------//
// XML-Array - Root //
//------------------------------------------------------------------//

dcl-ds Orders qualified;
Head likeds(Head);
end-ds;

//------------------------------------------------------------------//
// Template Head //
//------------------------------------------------------------------//

dcl-ds Head template qualified;
VersionNumber likeds(VersionNumber);
OrderNumber char(20);
Line likeds(Line) dim(05);
Cnt_Line int(10);
end-ds;

dcl-ds VersionNumber template qualified;
VersionName char(20);
VersionNo char(20);
end-ds;

//------------------------------------------------------------------//
// Template Line - Enthält die Produkte //
//------------------------------------------------------------------//

dcl-ds Line template qualified;
LineItemNumber char(03);
ProductNumber char(10);
end-ds;

//------------------------------------------------------------------//
// Processing //
//------------------------------------------------------------------//

main();

*inlr = *on;
//------------------------------------------------------------------//
// Main //
//------------------------------------------------------------------//
dcl-proc Main;

dcl-s LocOptions varchar(128); // XML-Options
dcl-s LocFile varchar(128); // File

dcl-s LocInd uns(10); // Index
dcl-s ItemNumber like(Line.LineItemNumber);
dcl-s ProductNumber like(Line.ProductNumber);

LocFile = '/Home/Import/xml/20191031_221735_1TJW5S_2.xml';

LocOptions = 'doc=file case=any allowextra=yes +
countprefix=cnt_ datasubf=data';

clear Orders; // Init XML-Struktur

xml-into Orders %xml(LocFile:LocOptions);

for LocInd = 1 to Orders.Head.Cnt_Line; // Loop Produkte
ItemNumber = Orders.Head.Line(LocInd).LineItemNumber;
ProductNumber = Orders.Head.Line(LocInd).ProductNumber;
endfor;

end-proc;
//------------------------------------------------------------------//

camouflage
26-11-19, 12:46
Lieber Rainer ...
... und wenn Du nun noch einen Konverter hast, der die XSD gleich in DS Templates umsetzt, bist Du mein Tagesheld. Good Job!

Rainer Ross
26-11-19, 13:41
Ein Konverter wäre richtig cool. Es würde auch mit SQL gehen



SELECT *
FROM XMLTABLE('/ORDERS/HEAD/LINE'
PASSING xmlparse(
DOCUMENT get_blob_from_file('/Home/Import/xml/mein.xml'))
COLUMNS
"ProductNumber" varchar(20) PATH 'ProductNumber',
"ProductName" varchar(20) PATH 'ProductName'
);

fdh
26-11-19, 13:49
Funktioniert super, dann halt total free. Gruß Franco FDH