How to parse XML in 3 different ways using kbmMW Pro, Enterprise and Community Edition.
This is a post based on a public question on the NLDelphi.com forums.
Having the following XML, how do can it be parsed?
const
XML: string =
'<?xml version="1.0"?>'+
'<DefaultBody>'+
'<Default>'+
' <Defaultcode>XML_BOLIMPORT_MAP</Defaultcode>'+
' <Omschrijving>Folder waar de xml bestanden staan, die gemaakt zijn door bolmate vanuit de inkoop</Omschrijving>'+
' <Waarde>Z:\tmp</Waarde>'+
'</Default>'+
'<Default>'+
' <Defaultcode>XML_DESTUSED_MAP</Defaultcode>'+
' <Omschrijving>XMLBestanden die verplaatst worden als ze klaar zijn</Omschrijving>'+
' <Waarde>Z:\tmp\xmlexport</Waarde>'+
'</Default>'+
'</DefaultBody>';
Into a list of TDef objects:
type
TDef = class
public
Defaultcode:string;
Omschrijving:string;
Waarde:string;
end;
TDefs = class(TObjectList<TDef>);
Contents
Method 1 – Basic XML parsing
We use the standard kbmMW DOM parser.
using
kbmMWXML;
...
function ParseXML1(const AString:string):TDefs;
var
xml:TkbmMWDOMXML;
i:integer;
data,node,child:TkbmMWDOMXMLNode;
def:TDef;
begin
Result:=TDefs.Create;
xml:=TkbmMWDOMXML.Create(AString);
try
data:=xml.Top; // Will usually be DefaultBody node
for i:=0 to data.Nodes.Count-1 do
begin
node:=data.Nodes[i];
if node.Name='Default' then
begin
def:=TDef.Create;
child:=node.ChildByName['Defaultcode'];
if child<>nil then
def.DefaultCode:=child.GetAsString;
child:=node.ChildByName['Omschrijving'];
if child<>nil then
def.Omschrijving:=child.GetAsString;
child:=node.ChildByName['Waarde'];
if child<>nil then
def.Waarde:=child.GetAsString;
Result.Add(def);
end;
end;
finally
xml.Free;
end;
end;
Method 2 – Using object notation
Notice there are many more dynamic ways to access the data using object notations than just this example.
uses
kbmMWXML,
kbmMWObjectNotation;
...
function ParseXML2(const AString:string):TDefs;
var
xml:TkbmMWDOMXML;
co:TkbmMWONCustomObject;
o:TkbmMWONObject;
def:TDef;
begin
Result:=TDefs.Create;
xml:=TkbmMWDOMXML.Create(AString);
try
def:=TDef.Create;
co:=xml.SaveToObjectNotation;
def.DefaultCode:=TkbmMWONNative(co.Path('DefaultBody/Default/0/Defaultcode',[mwonpoLastIsValue],'/',mwontString)).AsString;
def.Omschrijving:=TkbmMWONNative(co.Path('DefaultBody/Default/0/Omschrijving',[mwonpoLastIsValue],'/',mwontString)).AsString;
def.Waarde:=TkbmMWONNative(co.Path('DefaultBody/Default/0/Waarde',[mwonpoLastIsValue],'/',mwontString)).AsString;
Result.Add(def);
def:=TDef.Create;
def.DefaultCode:=TkbmMWONNative(co.Path('DefaultBody/Default/1/Defaultcode',[mwonpoLastIsValue],'/',mwontString)).AsString;
def.Omschrijving:=TkbmMWONNative(co.Path('DefaultBody/Default/1/Omschrijving',[mwonpoLastIsValue],'/',mwontString)).AsString;
def.Waarde:=TkbmMWONNative(co.Path('DefaultBody/Default/1/Waarde',[mwonpoLastIsValue],'/',mwontString)).AsString;
Result.Add(def);
finally
co.Free;
xml.Free;
end;
end;
Method 3 – Using object marshalling
This is by far the easiest way to parse the data, and also makes it very easy to generate XML from the objects again.
Notice that the TDef and TDefs class definitions has been augmented with a couple of attributes.
uses
Generics.Collections,
kbmMWObjectMarshal,
kbmMWXMLMarshal,
kbmMWRTTI;
type
[kbmMW_Root('Default',[mwrfIncludePublic])]
TDef = class
public
Defaultcode:string;
Omschrijving:string;
Waarde:string;
end;
[kbmMW_Root('DefaultBody')]
[kbmMW_Child('Default')]
TDefs = class(TObjectList<TDef>);
...
function ParseXML3(const AString:string):TDefs;
var
xml:TkbmMWXMLMarshal;
begin
xml:=TkbmMWXMLMarshal.Create;
try
Result:=xml.FromString<TDefs>(AString);
finally
xml.Free;
end;
end;
...
initialization
kbmMWRegisterKnownClasses([TDef,TDefs]);
![]()







