WikiCommons

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]);

Loading

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.