Parsing XML on Win32


First create the XML Parser binding by running (NOTE: Internet Explorer 5.0
required):

BindCOM C:\winnt\system32\msxml.dll XML_Parser

Where C:\winnt\system32\msxml.dll is your system dir (usually
C:\windows\system on Win9X)

Then create the test XML file test.xml - just a regular text file with the
following lines in it:

<employees>
  <employee>
    <name>James Smith</name>
    <birthdate>1970-09-30</birthdate>
    <ss_number>555-09-8410</ss_number>
    <position>file clerk</position>
  </employee>
  <employee>
    <name>Jane Jones</name>
    <birthdate>1968-03-22</birthdate>
    <ss_number>388-71-6662</ss_number>
    <position>marketing manager</position>
  </employee>
    <employee>
    <name>Mary Davis</name>
    <birthdate>1972-11-09</birthdate>
    <ss_number>884-99-3192</ss_number>
    <position>lead engineer</position>
  </employee>
</employees>

Next compile and run the XMLWalk program to make it happen:

with GNAT.IO; use GNAT.IO;

with Interfaces.C;

with GnatCom.Types;
with GnatCom.BSTR; use GnatCom.BSTR;
with GnatCom.Variant; use GnatCom.Variant;
with GnatCom.Initialize;

with MSXML;

with MSXML.IXMLDomDocument_Interface; 
use  MSXML.IXMLDomDocument_Interface; 

with MSXML.IXMLDomNode_Interface;
with MSXML.IXMLDomNodeList_Interface;
use MSXML;

procedure XMLWalk is

   use type GnatCom.Types.VARIANT_BOOL;

   -- Document   : Dispinterface_Type;
   Document   : MSXML.IXMLDomDocument_Interface.IXMLDomDocument_Type;
   Node       : IXMLDOMNode_Interface.IXMLDOMNode_Type;

   Input_File_Name : String := "test.xml";   
   Input_File : aliased GnatCom.Types.Variant :=
      To_Variant(Input_File_Name);

   Result     : GnatCom.Types.Variant_Bool;

   procedure Walk (Node  : IXMLDOMNode_Interface.IXMLDOMNode_Type;
                   Level : Integer := 0)
   is
      use type Interfaces.C.Long;

      Node_List : IXMLDOMNodeList_Interface.IXMLDOMNodeList_Type;
      M         : Interfaces.C.Long;      
      Name      : GnatCom.Types.BSTR;
      Value     : GnatCom.Types.Variant;
   begin
      begin
         Name := IXMLDOMNode_Interface.Get_NodeName(Node);
         Value := IXMLDOMNode_Interface.Get_NodeValue(Node);
      exception
         when others =>
            Initialize(Value);
      end;

      for N in 1 .. Level loop  Put(" ");  end loop;

      Put_Line("Name: " & To_Ada(Name) & 
               "  Value: " & To_Ada(Value) &
               "  Level: " & Integer'Image(Level));

      IXMLDOMNodeList_Interface.Attach
        (Node_List,
         IXMLDOMNode_Interface.Get_ChildNodes(Node));
         
      M := IXMLDOMNodeList_Interface.Get_Length(Node_List);   
      for N in 1 .. Level loop  Put(" ");  end loop;
      Put_Line("Nodes: "  & Natural'Image(Natural(M)));

      for N in 1 .. M loop
         declare
            Next_Node : IXMLDOMNode_Interface.IXMLDOMNode_Type;
         begin
            IXMLDOMNode_Interface.Attach
              (Next_Node,
               IXMLDOMNodeList_Interface.NextNode(Node_List));
            Walk(Next_Node, Level+1);
         end;
      end loop;
      
      for N in 1 .. Level loop  Put(" ");  end loop;
      Put_Line("------------------------------------------");
      GnatCom.BSTR.Free(Name);
      GnatCom.Variant.Free(Value);

   end Walk;

begin
   GnatCom.Initialize.Initialize_Com;
   Put_Line("Creating Document...");
   Create( Document, CLSID_DOMDocument);

   IXMLDOMDocument_Interface.Put_Async(Document, 0);

   Put_Line("Loading Document...");
   Result := IXMLDomDocument_Interface.Load(Document, Input_File);

   if Result /= 0 then
      Put_Line("Document Loaded...");
      MSXML.IXMLDomNode_Interface.Attach
        (Node, cloneNode(Document, -1));
      Walk(Node);
   end if;

   Free(Input_File);

end XMLWalk;


Contributed by: Al Christians
Contributed on: October 21, 2001
License: Public Domain

Back