<?xml version="1.0" encoding="UTF-8"?>

<!-- ====================================================================== -->
<!-- = chapter-1.xml                                                      = -->
<!-- = standard xml module guide - chapter 1                              = -->
<!-- ====================================================================== -->
<!-- = This  program  is  free  software; you  can redistribute it and/or = -->
<!-- = modify it provided that this copyright notice is kept intact.      = -->
<!-- = This program is distributed in the hope that it will be useful but = -->
<!-- = without  any  warranty;  without  even  the  implied  warranty  of = -->
<!-- = merchantability or fitness for  a  particular purpose. In no event = -->
<!-- = shall  the  copyright  holder be liable for any  direct, indirect, = -->
<!-- = incidental  or special  damages arising  in any way out of the use = -->
<!-- = of this software.                                                  = -->
<!-- ====================================================================== -->
<!-- = copyright (c) 2005-2007 - amaury darsch                            = -->
<!-- ====================================================================== -->

<chapter module="xml" number="1">
  <title>XML parsing</title>
  
  <p>
  This chapter is dedicated to the <afnix/> XML parsing, a
  subpart of the <em>standard xml processing</em> module. XML
  parsing refers to the ability to read valid xml constructs from an
  input stream and build an internal representation that is suitable
  for later processing. This chapter is designed for handling basic
  XML representation and does not cover the operations performed by a
  XML processor, such like entity expansion or DTD validation.
  </p>

  <p>
  All <afnix/> xml processing objects are located in the
  <code>afnix-xml</code> module. This module must be loaded prior
  any operation. Multiple calls to the module initialization routine
  are harmless. The interpreter method <code>library</code> loads a
  specific module by name. When the module has been loaded, the
  object are available in the <code>afnix:xml</code> nameset.
  </p>

  <example>
  interp:library "afnix-xml"
  </example>

  <!-- xml tree representation -->
  <section>
    <title>XML tree representation</title>

    <p>
    A xml document is represented with a tree. At the top of the tree
    is the <code>XmlRoot</code> object. The root object is not part of
    the document, but acts as the primary container for other
    objects. Inside <afnix/>, a xml document starts with a root node
    and all other child elements are <code>XmlNode</code> objects.
    </p>

    <!-- xml node base object -->
    <subsect>
      <title>Node base object</title>

      <p>
      The xml tree is built with the <code>XmlNode</code> object. The
      node object has different derivation depending on the required
      representation. For example, the <code>XmlRoot</code> object is
      derived from the <code>XmlNode</code> object. A node object can
      have child object unless the node is marked as an <em>empty
      node</em>. Trying to add node to an empty node results in an
      exception. A node can also be marked empty by the user. This
      situation typically arises with tag node which are used alone
      such like the <em>&lt;br/&gt;</em> xhtml empty tag or an empty
      paragraph <em>&lt;p/&gt;</em>. Although a xml node cannot be
      constructed directly, there is a predicate <code>node-p</code>
      that can be used to assert the node type.
      </p>

      <example>
      # check a node
      assert true (afnix:xml:node-p node)
      </example>

      <p>
      The <code>add-child</code> method adds a child node to the
      calling node. If the calling node is marked empty, an exception
      is raised when attempting to add the node. There is no limit for
      the number of nodes to add. In particular, when a text is to be
      added, care should be taken that there is no markup within that
      text. In doubt, the <code>parse</code> method should be used.
      </p>

      <example>
      # parse a text and add 3 child nodes
      p:parse "The quick brown &lt;b&gt;fox&lt;/b&gt; jumps over the lazy dog"
      </example>

      <p>
      In the previous example, the first child node is a
      <code>XmlText</code> node with the value <em>The quick brown
      </em>. The second node is a <code>XmlTag</code> node with name
      <em>b</em>. Finally, the third node is also a
      <code>XmlText</code> node with the value <em> jumps over the
      lazy dog</em>. It should be noted that the tag node has a child
      <code>XmlText</code> node with the value <em>fox</em>. This
      example also illustrates the power of the <code>parse</code>
      method which considerably simplify the creation of a xml
      tree. Finally, there is a subtle subject to be treated later
      which concerns the use of <em>character reference</em> with the
      <code>parse</code> method. Like any other xml parser, character
      references are evaluated during the parsing phase, thus
      providing no mechanism to create such reference. For this
      reason, a special class called <code>XmlCref</code> is provided
      in the module.
      </p>
    </subsect>

    <!-- xml tag object -->
    <subsect>
      <title>Tag object</title>

      <p>
      The <code>XmlTag</code> class is one of the most important class
      as it holds most of the xml constructs. A tag is defined by a
      name, a set of attributes and eventually a content. In its
      simplest form, a tag is created by name. With an additional
      boolean parameter, the tag can be marked as an empty node.
      </p>

      <example>
      # create an empty paragraph tag
      const p (afnix:xml:XmlTag "p" true)
      </example>

      <p>
      Adding attributes to a tag is imply a matter of method call. The
      <code>add-attribute</code> method operates with a
      <code>Property</code> object while the
      <code>set-attribute</code> operates with a name and a literal
      value. As a matter of fact, the attributes are stored internally
      as a property list.
      </p>

      <example>
      # &lt;p class="text"&gt;
      # create a paragraph tag
      const p (afnix:xml:XmlTag "p")
      # set the class attribute
      p:set-attribute "class" "text"
      </example>

      The node empty flag determines whether or not there is a end tag
      associated with a tag. If the empty flag is false, the node can
      have children nodes and is associated with a end tag.
      With the empty flag set, there is no child nodes. Such situation
      corresponds to the xml <em>/&gt;</em> notation.

      <example>
      # &lt;br/&gt;
      # create a br empty tag
      const br (afnix:xml:XmlTag "br" true)
      </example>
    </subsect>

    <!-- xml text node object -->
    <subsect>
      <title>Text objects</title>

      <p>
      The xml module provides two types of xml text node. The basic
      object is the <code>XmlText</code> node which is designed to
      hold some text without markup. It is this kind of nodes which is
      automatically instantiated by the <code>parse</code> method, as
      described earlier. The other object is the <code>XmlData</code>
      which corresponds to the xml <em>CDATA</em> special markup. With
      a character data node, the characters are not interpreted,
      including those that indicate markup starts like <em>&lt;</em>
      or end like <em>&gt;</em>. The <code>XmlData</code> is
      particularly used to store scripts or other <em>program text</em>
      inside a xml description. As an example, it is recommended to
      use a character data node inside a script tag with xhtml.
      </p>

      <example>
      &lt;script type="text/afnix"&gt;
      &lt;![CDATA[
        ... unescaped afnix program ...
      ]]&gt;
      &lt;/script&gt;
      </example>
    </subsect>
  </section>

  <!-- document reading -->
  <section>
    <title>Document reading</title>

    <p>
    A xml document is read by scanning an input stream an building a
    representation of the xml tree.
    </p>
    
    <!-- the document object -->
    <subsect>
      <title>The document object</title>

      <p>
      The <code>XmlDocument</code> object is a special object is
      designed to ease the reading process of an xml document. The
      process of creating a xml document consists of creating a
      document object, then binding a xml reader, parsing the input
      stream and finally storing the root node. When the operation is
      completed, the root node is available in the document object.
      </p>

      <example>
      # create a xml document
      const xdoc (afnix:xml:XmlDocument "example.xml")
      # get the root node
      const rppt (xdoc:get-root)
      </example>
    </subsect>

    <!-- the document root content -->
    <subsect>
      <title>The root node content</title>

      <p>
      When a document is parsed, the root node holds all the elements
      and markup sequentially. At this stage, it shall be noted that
      the element data are not expanded. Unlike a normal XML reader,
      the parameter entity are kept in the node data, are expended
      later by the XML processor.
      </p>
    </subsect>
  </section>
</chapter>

