Xml in Ada

Here’s the translation of the XML example from Go to Ada, formatted in Markdown suitable for Hugo:

with Ada.Text_IO;
with Ada.Strings.Unbounded;
with GNAT.XML.SAX.Reader;
with GNAT.XML.SAX.Attributes;

procedure XML_Example is
   use Ada.Text_IO;
   use Ada.Strings.Unbounded;

   type Plant is record
      Id     : Integer;
      Name   : Unbounded_String;
      Origin : Unbounded_String;
   end record;

   function To_String (P : Plant) return String is
   begin
      return "Plant id=" & Integer'Image(P.Id) & ", name=" & To_String(P.Name) &
             ", origin=" & To_String(P.Origin);
   end To_String;

   Coffee : Plant := (Id => 27, Name => To_Unbounded_String("Coffee"),
                      Origin => To_Unbounded_String("Ethiopia,Brazil"));

   package XML_Parser is new GNAT.XML.SAX.Reader;
   use XML_Parser;

   type Plant_Handler is new Reader with null record;

   overriding procedure Start_Element
     (Handler       : in out Plant_Handler;
      Namespace_URI : String;
      Local_Name    : String;
      QNAME         : String;
      Atts          : GNAT.XML.SAX.Attributes.Attributes'Class) is
   begin
      if Local_Name = "plant" then
         Coffee.Id := Integer'Value(Atts.Get_Value("id"));
      end if;
   end Start_Element;

   overriding procedure Characters
     (Handler : in out Plant_Handler;
      Ch      : Unicode.CES.Byte_Sequence) is
   begin
      if Handler.Get_Current_Element = "name" then
         Coffee.Name := To_Unbounded_String(Ch);
      elsif Handler.Get_Current_Element = "origin" then
         if Length(Coffee.Origin) > 0 then
            Append(Coffee.Origin, ",");
         end if;
         Append(Coffee.Origin, Ch);
      end if;
   end Characters;

   Handler : Plant_Handler;
   XML_Content : constant String :=
     "<?xml version=""1.0"" encoding=""UTF-8""?>" &
     "<plant id=""27"">" &
     "  <name>Coffee</name>" &
     "  <origin>Ethiopia</origin>" &
     "  <origin>Brazil</origin>" &
     "</plant>";

begin
   -- Emit XML representing our plant
   Put_Line(XML_Content);

   -- Parse the XML content
   Parse(Handler, XML_Content);

   -- Print the parsed Plant object
   Put_Line(To_String(Coffee));
end XML_Example;

This Ada code demonstrates XML handling using the GNAT.XML.SAX package, which provides SAX (Simple API for XML) parsing capabilities. Here’s a breakdown of the code:

  1. We define a Plant record type to represent our data structure.

  2. The To_String function is implemented to provide a string representation of a Plant object.

  3. We create a Coffee plant object with initial values.

  4. A custom Plant_Handler type is defined, inheriting from the SAX Reader. This handler implements the Start_Element and Characters procedures to parse the XML content.

  5. In the Start_Element procedure, we extract the “id” attribute when a “plant” element is encountered.

  6. The Characters procedure is used to populate the Name and Origin fields of our Plant object.

  7. In the main procedure, we first output the XML content as a string.

  8. Then, we use the SAX parser to parse this XML content, which populates our Coffee object.

  9. Finally, we print the parsed Plant object.

This example demonstrates basic XML handling in Ada, including creating XML content and parsing XML data. Note that Ada’s approach to XML handling is different from Go’s, as it uses a SAX parser instead of marshaling/unmarshaling to structs. However, this approach still allows for effective XML processing in Ada.

To run this program, you would typically compile it with a GNAT compiler and then execute the resulting binary:

$ gnatmake xml_example.adb
$ ./xml_example

This would output the XML content followed by the parsed Plant object information.