XML I/O

To compile this demonstration you need to add the package LazUtils to the project:
  • Select menu item Project > Project Inspector.
  • Click on the Add (+) icon and select the New Requirement tab.
  • Select LazUtils from the drop-down list.

The Lazarus Wiki XML Tutorial was a useful reference for the preparation of this demonstration. A copy of the console output and the content of books.xml follow the code.

program XML_IO_Demo;
uses
  laz2_XMLRead, laz2_XMLWrite, laz2_DOM;

type
  TBookRec = record
    title, author_surname, author_forename: string;
  end;

var
  BookRecs, BookRecs2: array[0..2] of TBookRec;
  WritingDoc, ReadingDoc: TXMLDocument;
  RootNode, ParentNode: TDOMNode;
  Children : TDOMNodeList;
  i, AttribNum, ChildNum: integer;

begin
  // Populate array of records
  BookRecs[0].title := 'On Chesil Beach';
  BookRecs[0].author_forename := 'Ian';
  BookRecs[0].author_surname := 'McEwan';

  BookRecs[1].title := 'Yellow Dog';
  BookRecs[1].author_forename := 'Martin';
  BookRecs[1].author_surname := 'Amis';

  BookRecs[2].title := 'Malone Dies';
  BookRecs[2].author_forename := 'Samuel';
  BookRecs[2].author_surname := 'Beckett';

  try
    WritingDoc := TXMLDocument.Create;
    RootNode := WritingDoc.CreateElement('books'); // Creating a root node
    WritingDoc.AppendChild(RootNode);  // Saving root node
    for i := 0 to 2 do
      begin
        RootNode := WritingDoc.DocumentElement; // Creating a parent node
        parentNode := WritingDoc.CreateElement('book');
        TDOMElement(parentNode).SetAttribute('title', BookRecs[i].title);       // create atributes to parent node
        TDOMElement(parentNode).SetAttribute('author_surname', BookRecs[i].author_surname);
        TDOMElement(parentNode).SetAttribute('author_forename', BookRecs[i].author_forename);
        RootNode.AppendChild(ParentNode);  // Saving parent node
      end;
    writeXMLFile(WritingDoc, 'books.xml'); // write to XML file
  finally
    WritingDoc.Free;
  end;

  try
    ReadXMLFile(ReadingDoc, 'books.xml'); // Reading in xml file from disk
    Children := ReadingDoc.DocumentElement.ChildNodes;
    for ChildNum := 0 to Children.Count - 1 do
      begin
        for AttribNum := 0 to 2 do
          write(Children[ChildNum].Attributes.Item[AttribNum].NodeValue + '   ');
        writeln;
        BookRecs2[ChildNum].title := Children[ChildNum].Attributes.Item[0].NodeValue;
        BookRecs2[ChildNum].author_surname := Children[ChildNum].Attributes.Item[1].NodeValue;
        BookRecs2[ChildNum].author_forename := Children[ChildNum].Attributes.Item[2].NodeValue;
      end;
  finally
    ReadingDoc.Free;
  end;
  writeln('First author in array of records read from XML file: ', BookRecs2[0].author_surname);
  writeln('Second title in array of records read from XML file: ', BookRecs2[1].title);
  readln;
end.

Console output:

On Chesil Beach   McEwan   Ian
Yellow Dog   Amis   Martin
Malone Dies   Beckett   Samuel
First author in array of records read from XML file: McEwan
Second title in array of records read from XML file: Yellow Dog

Content of books.xml:

<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book title="On Chesil Beach" author_surname="McEwan" author_forename="Ian"/>
  <book title="Yellow Dog" author_surname="Amis" author_forename="Martin"/>
  <book title="Malone Dies" author_surname="Beckett" author_forename="Samuel"/>
</books>

XSL Style Sheet for Presenting Contents of XML File

W3Schools has a useful, well-explained section on the EXtensible Stylesheet Language.

Using the style sheet books.xsl (following the screenshot), a browser converts selected contents of the XML file to HTML and displays it. To link to the style sheet, insert this line of code before <Books> in the XML file above :

<?xml-stylesheet type="text/xsl" href="books.xsl"?>
Put books.xsl in the same folder as books.xml and open the latter with a web browser such as Firefox.
Screenshot of result of transformation

Screenshot of result of transformation

Code of books.xsl

We include in the output both CSS and HTML. Two of the three fields are displayed, the surnames are arranged in alphabetical order by applying a sort, and an if selection excludes the surname McEwan.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
    <head>
      <style>
        thead 
        {
          color: #FF7700;
          background-color: #EEEEEE;  
        }

        td, th
        {
          border-left: 1px solid #FF7700;
          border-top: 1px solid #FF7700;
          width: 150px;
        }

        table
        {
          border-right:1px solid #FF7700;
          border-bottom:1px solid #FF7700;
        }

        h3
        {
          color: #FF7700;
        }
      </style>
    </head>
    <body>
      <h3>Books</h3>
      <table cellpadding="0" cellspacing="0">
        <thead>
          <th>Title</th>
          <th>Surname</th>
        </thead>
        <xsl:for-each select="books/book">
        <xsl:sort select="@author_surname"/>
        <xsl:if test="not(@author_surname = 'McEwan')">      
          <tr>
            <td><xsl:value-of select="@title"/></td>
            <td><xsl:value-of select="@author_surname"/></td>
          </tr>
          </xsl:if>
        </xsl:for-each>
      </table>
    </body>
  </html>
</xsl:template>
</xsl:stylesheet>
Programming - a skill for life!

Input from keyboard and file and output to monitor, file and printer