<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
<book>
  <title>The DOMIT! XML Parser Manual</title>

  <chapter>
    <title>Overview of XML</title>

    <section>
      <title>Intro to XML</title>

      <para><ulink url="http://www.w3.org/TR/REC-xml/">XML</ulink> (Extensible
      Markup Language) is a standard for encapsulating textual data. XML is
      strictly structured, but also human readable.</para>

      <para>Having a strictly defined format makes it easier for computer
      programs (i.e., XML parsers) to build, extract, manipulate, and exchange
      the data. Since XML is written in human readable text and not binary
      format, it is much more convenient for people to work with on a daily
      basis.</para>

      <para>This simple balance of structure and readability is one of the
      primary reasons that XML has seen such widespread adoption over recent
      years.</para>

      <para>The following description of a person's cd music collection is one
      possible example of XML formatted text:</para>

      <programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>

      <para>As should be apparent from the example, XML has a tree-like
      structure. This is referred to as a
      <emphasis>Document</emphasis>.</para>
    </section>

    <section>
      <title>Types of XML Content</title>

      <para>There are a varierty of different ways of demarcating content in
      an XML Document. The following sections presents a brief overview of
      some of these ways.</para>

      <section>
        <title>XML Elements</title>

        <para>An <emphasis>Element</emphasis> in XML is a type of content
        whose primary purpose is to <emphasis>contain other
        content</emphasis>. Elements are like bookends, and therefore consist
        of two parts: a <emphasis>start tag</emphasis> and an <emphasis>end
        tag</emphasis>.</para>

        <para>Take a look at the first line of text in the cd library example:
        <computeroutput>&lt;cdlibrary&gt;</computeroutput>.</para>

        <para>This is an example of a start tag. A start tag always:</para>

        <itemizedlist>
          <listitem>
            <para>begins with a left angle bracket:
            <computeroutput>&lt;</computeroutput></para>
          </listitem>

          <listitem>
            <para>ends with a right angle bracket:
            <computeroutput>&gt;</computeroutput></para>
          </listitem>

          <listitem>
            <para>has a name:
            <computeroutput>cdlibrary</computeroutput></para>
          </listitem>
        </itemizedlist>

        <para>At the bottom of the XML document is an end tag, which has a
        slightly different format:
        <computeroutput>&lt;/cdlibrary&gt;</computeroutput>.</para>

        <para>An end tag always:</para>

        <itemizedlist>
          <listitem>
            <para>begins with a left angle bracket and a forward slash:
            <computeroutput>&lt;/</computeroutput></para>
          </listitem>

          <listitem>
            <para>ends with a right angle bracket:
            <computeroutput>&gt;</computeroutput></para>
          </listitem>

          <listitem>
            <para>has a name identical to its matching start tag:
            <computeroutput>cdlibrary</computeroutput></para>
          </listitem>
        </itemizedlist>

        <para>An XML element can contain other types of XML content, including
        other elements. For example, the
        <computeroutput>&lt;person&gt;</computeroutput> element below contains
        a single <computeroutput>&lt;name&gt;</computeroutput> element:</para>

        <programlisting>&lt;person&gt;
  &lt;name&gt;John Heinstein&lt;/name&gt;
&lt;/person&gt;</programlisting>

        <para>It is possible to have an element containing
        <emphasis>no</emphasis> XML content. This is referred to as an
        <emphasis>empty element</emphasis>. There is a shorthand notation for
        representing an empty element:</para>

        <programlisting>&lt;someEmptyElement/&gt;</programlisting>

        <para>The longhand equivalent of this is:</para>

        <programlisting>&lt;someEmptyElement&gt;&lt;/someEmptyElement&gt;</programlisting>
      </section>

      <section>
        <title>XML Attributes</title>

        <para>Take a look at the first <computeroutput>cd</computeroutput>
        element in <computeroutput>cdlibrary</computeroutput>:</para>

        <programlisting>&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;</programlisting>

        <para>Some additional information is present in the start tag:
        <computeroutput>discid="bb0c3c0c"</computeroutput>. This is a type of
        XML content referred to as an <emphasis>Attribute</emphasis>. An
        attribute is used to store short, simple units of text.</para>

        <para>An attribute always:</para>

        <itemizedlist>
          <listitem>
            <para>contains a unique named key, such as:
            <computeroutput>discid</computeroutput></para>
          </listitem>

          <listitem>
            <para>followed by an equal sign:
            <computeroutput>=</computeroutput></para>
          </listitem>

          <listitem>
            <para>followed by a value contained in either single or double
            quotes: <computeroutput>"bb0c3c0c"</computeroutput></para>
          </listitem>
        </itemizedlist>

        <para>There can be multiple attributes in any start tag, as long as
        the attribute names are unique. For example:</para>

        <programlisting>&lt;point x='10' y='35'/&gt;</programlisting>
      </section>

      <section>
        <title>Character Data</title>

        <para>Textual XML content not stored in attributes is referred to as
        <emphasis>Character Data</emphasis>. Character data is always
        contained within elements, as we can see in the following example from
        the <emphasis>cdlibrary</emphasis> document</para>

        <programlisting>&lt;name&gt;Robbie Fulks&lt;/name&gt;</programlisting>

        <section>
          <title>Illegal Characters</title>

          <para>There are two reserved characters which cannot be present in
          valid XML character data. These are the ampersand character
          (<computeroutput>&amp;</computeroutput>) and the left angle bracket
          (<computeroutput>&lt;</computeroutput>).</para>

          <para>If either of these characters need to be present in XML text,
          it must be <emphasis>escaped</emphasis>. This is done by
          substituting the <emphasis>entity equivalent</emphasis> of the
          character.</para>

          <itemizedlist>
            <listitem>
              <para>The entity equivalent of the ampersand
              (<computeroutput>&amp;</computeroutput>) is the string
              <computeroutput>&amp;amp</computeroutput>;</para>
            </listitem>

            <listitem>
              <para>The entity equivalent of the left angle bracket
              (<computeroutput>&lt;</computeroutput>) is the string
              <computeroutput>&amp;lt;</computeroutput></para>
            </listitem>
          </itemizedlist>

          <para>To represent the string <computeroutput>x &lt;= y +
          1</computeroutput> as character data, for example, one must escape
          the left angle bracket:</para>

          <programlisting>&lt;relationship&gt;x &amp;lt;= y + 1&lt;/relationship&gt;</programlisting>

          <para><remark>Note: To allow attribute values to contain both single
          and double quotes, the apostrophe or single-quote character
          (<computeroutput>'</computeroutput>) may be represented as
          <computeroutput>&amp;apos;</computeroutput> and the double-quote
          character (<computeroutput>"</computeroutput>) as
          <computeroutput>&amp;quot;</computeroutput></remark></para>
        </section>

        <section>
          <title>CDATA Sections</title>

          <para>Sometimes your XML data contains many illegal characters that
          must be escaped -- such as when you need to store HTML content
          within XML content:</para>

          <para><programlisting>&lt;htmlcode&gt;&amp;lt;img src="http://www.someurl.com/pic.jpg" /&gt;&lt;/htmlcode&gt;</programlisting></para>

          <para>It is not only work intensive to escape many illegal
          characters, but the readability of your document suffers.</para>

          <para>There is a special construct called a <emphasis>CDATA
          Section</emphasis> that is reserved for demarcating text data that
          can be written in its literal form. The following example rewites
          the above <computeroutput>&lt;htmlcode&gt;</computeroutput> example
          as a CDATA Section:</para>

          <programlisting>&lt;htmlcode&gt;&lt;![CDATA[&lt;img src="http://www.someurl.com/pic.jpg"" /&gt;]]&gt;&lt;/htmlcode&gt;</programlisting>

          <para>As you can see there is no need to escape the left angle
          bracket beginning the <computeroutput>&lt;img</computeroutput>
          tag.</para>

          <para>A CDATA Section always:</para>

          <itemizedlist>
            <listitem>
              <para>begins with the string
              <computeroutput>&lt;![CDATA[</computeroutput></para>
            </listitem>

            <listitem>
              <para>ends with the string
              <computeroutput>]]&gt;</computeroutput></para>
            </listitem>
          </itemizedlist>

          <para><remark>Note: if the string
          <computeroutput>]]&gt;</computeroutput> is contained within a CDATA
          Section, the right angle bracket
          (<computeroutput>&gt;</computeroutput>)must be escaped as
          &amp;<computeroutput>gt; </computeroutput>so that it will not be
          confused with the terminating CDATA Section string. </remark></para>
        </section>
      </section>

      <section>
        <title>Comments</title>

        <para>An XML <emphasis>Comment</emphasis> is a construct for adding
        remarks to your XML. It is similar to an HTML comment in that
        it:</para>

        <itemizedlist>
          <listitem>
            <para>begins with the string
            <computeroutput>&lt;!--</computeroutput></para>
          </listitem>

          <listitem>
            <para>ends with the string
            <computeroutput>--&gt;</computeroutput></para>
          </listitem>
        </itemizedlist>

        <para>A comment could be added to the cdlibrary example like
        this:</para>

        <programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;!-- Not many cds left after I got robbed --&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>
      </section>

      <section>
        <title>Processing Instructions</title>

        <para>An XML <emphasis>Processing Instruction</emphasis> indicates to
        an application that it must perform some processing operation.</para>

        <para>Every XML document is required to begin with a special type of
        processing instruction know as an <emphasis>XML Declaration</emphasis>
        (in practice, the XML declaration is often omitted):</para>

        <para><programlisting>&lt;?xml version="1.0"?&gt;</programlisting></para>

        <para>A processing instruction:</para>

        <itemizedlist>
          <listitem>
            <para>begins with the string
            <computeroutput>&lt;?</computeroutput></para>
          </listitem>
        </itemizedlist>

        <itemizedlist>
          <listitem>
            <para>followed by the <emphasis>target</emphasis> of the operation
            (the application to which the operation is to be directed): e.g.
            <computeroutput>xml</computeroutput></para>
          </listitem>

          <listitem>
            <para>followed by the <emphasis>data</emphasis> for the
            application to process: e.g.
            <computeroutput>version="1.0"</computeroutput></para>
          </listitem>

          <listitem>
            <para>ending with the string
            <computeroutput>?&gt;</computeroutput></para>
          </listitem>
        </itemizedlist>

        <para>Another example of a processing instruction is found in the
        declaration of PHP code within an HTML page:</para>

        <para><programlisting>&lt;?php  
//code here
?&gt;</programlisting></para>

        <para>The target "php" informs a web server to process the subsequent
        data with a PHP interpreter rather than as HTML code.</para>
      </section>

      <section>
        <title>Document Type Declarations</title>

        <para>A <emphasis>Document Type Declaration</emphasis> is a mechanism
        for defining what is an acceptable structure for an XML document. A
        <emphasis>validating XML parser</emphasis> can compare an XML document
        to its DTD and determine whether it is valid or not.</para>

        <para>A DTD follows the XML declaration and comes before any actual
        XML data.</para>

        <para>The following is an example of a DTD for an XML document
        containing a single element named "foo":</para>

        <para><programlisting>&lt;!DOCTYPE foo [
  &lt;!ELEMENT foo (#PCDATA)&gt;
]&gt;</programlisting></para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>Overview of the DOM</title>

    <section>
      <title>Intro to the DOM</title>

      <para>When one speaks of the <ulink
      url="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html">DOM
      (Document Object Model)</ulink>, one is not is not referring to XML
      <emphasis>per se</emphasis>. Rather, the DOM is <emphasis>one of a
      number of different approaches to conceptualizing, parsing, and
      interacting with XML content</emphasis>.</para>

      <para>The DOM processes XML by creating an object called a
      <emphasis>Node</emphasis> out of each unit of content in an XML
      document. Nodes are assembled into a hierarchical collection called a
      <emphasis>DOM Document</emphasis>.</para>

      <para>The entire XML document is held in memory at once, which allows
      the collection of nodes to be traversed easily. The DOM approach can,
      however, be memory intensive for larger XML documents.</para>

      <para>The DOM also describes a number of methods and properties that
      allow the user to interact programatically with the nodes of a DOM
      Document.</para>

      <para>We will be examining some of these methods and properties in the
      following tutorial.</para>
    </section>

    <section>
      <title>Types of DOM Nodes</title>

      <para>The DOM specification delineates a number of different kinds of
      nodes, each of which correspond to the different kinds of XML content. A
      set of three node properties are used to distinguish one kind of node
      from another:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>node type</emphasis>: an integer from 1 to 12
          specifying the type of node</para>
        </listitem>

        <listitem>
          <para><emphasis>node name</emphasis>: the name of the node, can have
          various values depending on node type</para>
        </listitem>

        <listitem>
          <para><emphasis>node value</emphasis>: the value of the node, can
          various values depending on node type</para>
        </listitem>
      </itemizedlist>

      <section>
        <title>Document Nodes</title>

        <para>A <emphasis>Document Node</emphasis> represents the DOM document
        itself -- the entire collection of nodes in a. It has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>9</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of
            <computeroutput>#document</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of <computeroutput>null</computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>Element Nodes</title>

        <para>An <emphasis>Element Node</emphasis> represents an XML Element.
        Take for instance the following
        <computeroutput>&lt;fullname&gt;</computeroutput> element:</para>

        <programlisting>&lt;fullname&gt;John Heinstein&lt;/fullname&gt;</programlisting>

        <para>This element has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>1</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of
            <computeroutput>fullname</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of <computeroutput>null</computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>Attribute Nodes</title>

        <para>An <emphasis>Attribute Node</emphasis> represents an XML
        Attribute. Take for instance the following
        <computeroutput>serial</computeroutput> attribute:</para>

        <programlisting>&lt;item serial="123456"/&gt;</programlisting>

        <para>This attribute has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>2</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of
            <computeroutput>serial</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of
            <computeroutput>123456</computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>Text Nodes</title>

        <para>A <emphasis>Text Node</emphasis> represents XML Character Data
        that is not specified as a CDATA Section. Take for instance the text
        content bounded by the
        <computeroutput>&lt;fullname&gt;</computeroutput> element:</para>

        <programlisting>&lt;fullname&gt;John Heinstein&lt;/fullname&gt;</programlisting>

        <para>This text node has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>3</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of <computeroutput>#text</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of <computeroutput>John
            Heinstein</computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>CDATA Section Nodes</title>

        <para>A <emphasis>CDATA Section Node</emphasis> represents XML
        Character Data that is specified as a CDATA Section. Take the
        following CDATA Section:</para>

        <programlisting>&lt;htmlcode&gt;&lt;![CDATA[&lt;img src="http://www.someurl.com/pic.jpg"" /&gt;]]&gt;&lt;/htmlcode&gt;</programlisting>

        <para>This CDATA Section has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>4</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of
            <computeroutput>#cdata-section</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of <computeroutput>&lt;img
            src="http://www.someurl.com/pic.jpg""
            /&gt;</computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>Comment Nodes</title>

        <para>A <emphasis>Comment Node</emphasis> represents an XML comment.
        Take the following XML comment:</para>

        <programlisting>&lt;!-- Not many cds left after I got robbed --&gt;</programlisting>

        <para>This comment node has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>8</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of
            <computeroutput>#comment</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of <computeroutput> Not many cds left after I
            got robbed </computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>Processing Instruction Nodes</title>

        <para>A <emphasis>Processing Instruction Node</emphasis> represents an
        XML processing instruction. The most common processing instruction
        that you will find in a DOM Document is the XML Declaration:</para>

        <programlisting>&lt;?xml version="1.0"?&gt;</programlisting>

        <para>This processing instruction node has:</para>

        <itemizedlist>
          <listitem>
            <para>a node type of <computeroutput>7</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node name of <computeroutput>xml</computeroutput></para>
          </listitem>

          <listitem>
            <para>a node value of <computeroutput>version="1.0"
            </computeroutput></para>
          </listitem>
        </itemizedlist>
      </section>

      <section>
        <title>Document Type Declarations</title>

        <para>A <emphasis>Document Type Declaration</emphasis> represents an
        XML document type declaration.</para>

        <para>DOMIT! is a non-validating parser and therefore does not check
        the validity of an XML document against the DTD. It simply stores a
        string representation of the DTD.</para>
      </section>
    </section>

    <section>
      <title>The Structure of a DOM Document</title>

      <para>The nodes of a DOM Document are structured as a tree of branching
      nodes. The terminology to describe the relationship of these nodes is
      similar to how we would describe the relationship between individuals in
      a family tree.</para>

      <para>Let us use the cdlibrary XML to illustrate this:</para>

      <programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>

      <section>
        <title>Child Nodes</title>

        <para>All nodes that are direct descendants of a node are referred to
        as its <emphasis>Child Nodes</emphasis>.</para>

        <para>Only nodes of type <emphasis>element</emphasis> are permitted to
        contain a child nodes collection. Children themselves, however, can be
        of various node types, including element nodes, text and CDATA Section
        nodes, and comment nodes.</para>

        <para>In the cdlibrary example:</para>

        <itemizedlist>
          <listitem>
            <para>the <computeroutput>&lt;cdlibrary&gt;</computeroutput>
            element contains three child nodes of type element (the three
            <computeroutput>cd</computeroutput> nodes)</para>

            <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  <emphasis role="bold">&lt;cd discid="bb0c3c0c"&gt;</emphasis>
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  <emphasis role="bold">&lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;</emphasis>
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  <emphasis role="bold">&lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;</emphasis>
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  <emphasis role="bold">&lt;/cd&gt;</emphasis>
&lt;/cdlibrary&gt;</programlisting></para>
          </listitem>

          <listitem>
            <para>each <computeroutput>&lt;cd&gt;</computeroutput> node
            contains two child nodes of type element (a
            <computeroutput>&lt;name&gt;</computeroutput> node and a
            <computeroutput>&lt;title&gt;</computeroutput> node)
            <programlisting>&lt;cd discid="bb0c3c0c"&gt;
  <emphasis role="bold">&lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;</emphasis>
&lt;/cd&gt;</programlisting></para>
          </listitem>

          <listitem>
            <para>each <computeroutput>&lt;name&gt;</computeroutput> node
            contains one child node of type text</para>

            <para><programlisting>&lt;name&gt;<emphasis role="bold">Richard Thompson</emphasis>&lt;/name&gt;</programlisting></para>
          </listitem>

          <listitem>
            <para>each <computeroutput>&lt;title&gt;</computeroutput> node
            contains one child node of type text</para>

            <para><programlisting>&lt;title&gt;<emphasis role="bold">Laugh</emphasis>&lt;/title&gt;</programlisting></para>
          </listitem>
        </itemizedlist>

        <para>A child node is referred to by its <emphasis>numerical
        index</emphasis> in the child nodes collection. The first child node
        is generally assigned an index of 1, although for technical reasons
        some DOM implementations will start at 0.</para>

        <para>If an element contains no children, it will still have an child
        nodes collection (that is empty).</para>

        <para><remark>Note: Attribute nodes are not included in the child
        nodes collection. These are in a separate collection reserved
        specifically for attributes.</remark></para>

        <section>
          <title>First Child</title>

          <para>The <emphasis>First Child</emphasis> is a DOM property that
          refers to the first child node in a child nodes collection.</para>

          <para>In our cdlibrary example, the first child of each of the
          <computeroutput>&lt;cd&gt;</computeroutput> nodes is the element
          node <computeroutput>&lt;name&gt;</computeroutput>.</para>

          <para><programlisting>&lt;cd discid="cf11720f"&gt;
  <emphasis role="bold">&lt;name&gt;Keller Williams&lt;/name&gt;</emphasis>
  &lt;title&gt;Laugh&lt;/title&gt;
&lt;/cd&gt;</programlisting></para>

          <para>If an element contains no child nodes, the first child is
          <computeroutput>null</computeroutput>.</para>
        </section>

        <section>
          <title>Last Child</title>

          <para>The <emphasis>Last Child</emphasis> is a DOM property that
          refers to the last child node in the child nodes collection.</para>

          <para>In our cdlibrary example, the last child of each of the
          <computeroutput>&lt;cd&gt;</computeroutput> nodes is the element
          node <computeroutput>&lt;title&gt;</computeroutput>.</para>

          <para><programlisting>&lt;cd discid="cf11720f"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  <emphasis role="bold">&lt;title&gt;Laugh&lt;/title&gt;</emphasis>
&lt;/cd&gt;</programlisting></para>

          <para>If an element contains no child nodes, the last child is
          <computeroutput>null</computeroutput>.</para>
        </section>
      </section>

      <section>
        <title>Parent Nodes</title>

        <para>In the same way that one can travel down the hierarchy of a DOM
        document via the child nodes collection, the DOM specifies a way to
        travel <emphasis>up</emphasis> the hierarchy. The ancestor of any node
        is referred to as its <emphasis>Parent Node</emphasis>.</para>

        <para>In our cdlibrary example:</para>

        <itemizedlist>
          <listitem>
            <para>the parent node of each
            <computeroutput>&lt;cd&gt;</computeroutput> element is the
            <computeroutput>&lt;cdlibrary&gt;</computeroutput> element</para>
          </listitem>

          <listitem>
            <para>the parent node of each
            <computeroutput>&lt;name&gt;</computeroutput> element is its
            containing <computeroutput>&lt;cd&gt;</computeroutput>
            element</para>
          </listitem>

          <listitem>
            <para>the parent node of each
            <computeroutput>&lt;title&gt;</computeroutput> element is its
            containing <computeroutput>&lt;cd&gt;</computeroutput>
            element</para>
          </listitem>

          <listitem>
            <para>the parent node of the text contained in the
            <computeroutput>&lt;name&gt;</computeroutput> element is the
            <computeroutput>&lt;name&gt;</computeroutput> element</para>
          </listitem>

          <listitem>
            <para>the parent node of the text contained in the
            <computeroutput>&lt;title&gt;</computeroutput> element is the
            <computeroutput>&lt;title&gt;</computeroutput> element</para>
          </listitem>
        </itemizedlist>

        <para><remark>Note: Attributes do not contain a reference to parent
        nodes.</remark></para>
      </section>

      <section>
        <title>Sibling Nodes</title>

        <para>The DOM specifies an explicit relationship between nodes that
        occupy the same level of a DOM tree. These nodes are referred to as
        <emphasis>Sibling Nodes</emphasis>.</para>

        <para>One might think of the relationship between sibling nodes as the
        links in a chain. Each node knows about the node immediately preceding
        it and the node immediately following it.</para>

        <section>
          <title>Previous Sibling</title>

          <para>The node immediately <emphasis>preceding</emphasis> any node
          in a sibling chain is referred to as its <emphasis>Previous
          Sibling</emphasis>.</para>

          <para>In our cdlibrary example:</para>

          <itemizedlist>
            <listitem>
              <para>the previous sibling of each
              <computeroutput>&lt;title&gt;</computeroutput> element is the
              <computeroutput>&lt;name&gt; </computeroutput>element</para>
            </listitem>

            <listitem>
              <para>the previous sibling of each
              <computeroutput>&lt;name&gt;</computeroutput> element is
              <computeroutput>null</computeroutput></para>
            </listitem>
          </itemizedlist>

          <para><remark>Note: If a node has no previous sibling, there still
          exists a previous sibling reference, but it is
          <computeroutput>null</computeroutput>.</remark></para>
        </section>

        <section>
          <title>Next Sibling</title>

          <para>The node immediately <emphasis>following</emphasis> any node
          in a sibling chain is referred to as its <emphasis>Next
          Sibling</emphasis>.</para>

          <para>In our cdlibrary example:</para>

          <itemizedlist>
            <listitem>
              <para>the next sibling of each
              <computeroutput>&lt;name&gt;</computeroutput> element is the
              <computeroutput>&lt;title&gt;</computeroutput> element</para>
            </listitem>

            <listitem>
              <para>the next sibling of each
              <computeroutput>&lt;title&gt;</computeroutput> element is
              <computeroutput>null</computeroutput></para>
            </listitem>
          </itemizedlist>
        </section>
      </section>

      <section>
        <title>Attribute Nodes</title>

        <para>Each element node contains an <emphasis>Attributes
        list</emphasis>, or a reference to the collection of attributes
        assigned to it. In the following example, the
        <computeroutput>&lt;item&gt;</computeroutput> element contains a list
        of five attributes:</para>

        <para><programlisting>&lt;item desc="post" material="steel" length="120" diameter="5" price="0.75"/&gt; </programlisting>These
        attributes can be accessed either by <emphasis>name</emphasis> or
        <emphasis>numerical index</emphasis>.</para>
      </section>

      <section>
        <title>Owner Document</title>

        <para>Each node in a DOM Document -- with the exclusion of attribute
        nodes -- contains a reference to the DOM Document that contains it.
        This is referred to as the <emphasis>Owner Document</emphasis>
        property of a node.</para>
      </section>

      <section>
        <title>Document Element</title>

        <para>The root element of a DOM Document is always referred to as the
        <emphasis>Document Element</emphasis>.</para>

        <para>In our cdlibrary example, the document element would be the
        <computeroutput>&lt;cdlibrary&gt;</computeroutput> node.</para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>Installing DOMIT</title>

    <section>
      <title>What is DOMIT!?</title>

      <para>DOMIT! is an <ulink
      url="http://www.w3.org/TR/REC-xml/">XML</ulink> parser that is mostly
      consistent with the <ulink
      url="http://www.w3.org/TR/DOM-Level-2-Core/">Document Object Model (DOM)
      Level 2 specification</ulink>.</para>

      <para>DOMIT! is not an extension; it is written purely in <ulink
      url="http://www.php.net">PHP</ulink> and should work in any PHP 4 or 5
      environment, regardless of restrictions put in place by your web hosting
      provider.</para>

      <para>It has been designed for speed and ease of use. However, because
      DOMIT! is composed of interpreted rather than compiled code, you may see
      sluggish performance with large XML files on a low-memory server.</para>

      <para>DOMIT! must be used in conjunction with a <ulink
      url="http://www.saxproject.org/">SAX</ulink> parser. By default, you
      have the option of using either the <ulink
      url="http://www.php.net/xml">Expat parser</ulink> (available with most
      later distributions of PHP) or the <ulink
      url="http://www.engageinteractive.com/saxy/">SAXY</ulink> parser -
      another purely PHP-based parser developed by Engage Interactive.</para>

      <para>As of version 0.9, DOMIT! now includes a lightweight version named
      DOMIT! Lite, which is slightly faster, especially for larger documents.
      However, it does not handle parsing of the xml prolog, processing
      instructions, comments, and certain other functionality.</para>

      <para>As of version 0.96, DOMIT! has support for <ulink
      url="http://www.w3.org/TR/REC-xml-names/">XML namespaces</ulink>.</para>

      <para>Version 0.98 brings PHP5 compatability.</para>
    </section>

    <section>
      <title>Installing DOMIT!</title>

      <para>Since DOMIT! is not an extension, it requires no special setup on
      your web server. You will, however, need to have the following files
      present on your server filesystem:<itemizedlist>
          <listitem>
            <para><filename>xml_domit_include.php</filename> - include file
            for DOMIT!, ensures that include paths are resolved
            properly.</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_shared.php</filename> - shared code for
            DOMIT! and DOMIT! Lite</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_parser.php</filename> - the main DOMIT!
            php file.</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_utilities.php</filename> - required if
            you want to render your XML as a normalized (whitespace formatted)
            string or if you want to use the parseXML method of
            DOMIT_Document.</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_getelementsbypath.php</filename> -
            required if you would like to search for elements in your
            DOMIT_Document using a path-based syntax.</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_nodemaps.php</filename> - data
            structures that contain collections of nodes</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_nodetools.php</filename> - a collection
            of tools to assist in XML processing</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_cache.php</filename> - simple caching
            class for DOMIT! and DOMIT! Lite documents</para>
          </listitem>

          <listitem>
            <para><filename>xml_saxy_parser.php</filename> - required if you
            would like to use the SAXY parser with DOMIT! instead of the Expat
            parser.</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_doctor.php</filename> - class for
            repairing malformed xml</para>
          </listitem>

          <listitem>
            <para><filename>xml_domit_xpath.php</filename> - experimental
            support for <ulink url="http://www.w3.org/TR/xpath">XPath</ulink>
            queries</para>
          </listitem>

          <listitem>
            <para><filename>php_file_utilities.php</filename> - generic file
            input / output utilities</para>
          </listitem>

          <listitem>
            <para><filename>php_http_client_generic.php</filename> - generic
            http client class</para>
          </listitem>

          <listitem>
            <para><filename>php_http_client_include.php</filename> - include
            file for http client class</para>
          </listitem>

          <listitem>
            <para><filename>php_http_connector.php</filename> - helper class
            for php_http_client</para>
          </listitem>

          <listitem>
            <para><filename>php_http_exceptions.php</filename> - http
            exceptions class</para>
          </listitem>

          <listitem>
            <para><filename>php_http_proxy.php</filename> - http proxy
            class</para>
          </listitem>
        </itemizedlist></para>
    </section>

    <section>
      <title>Installing DOMIT! Lite</title>

      <para>If you wish to use DOMIT! Lite, a leaner and somewhat faster
      (although fewer-featured) version of DOMIT!, you will require the
      following files:</para>

      <itemizedlist>
        <listitem>
          <para><filename>xml_domit_lite_include.php</filename> - include file
          for DOMIT! Lite, ensures that include paths are resolved
          properly.</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_shared.php</filename> - shared code for
          DOMIT! and DOMIT! Lite.</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_lite_parser.php</filename> - the main
          DOMIT! Lite php file.</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_utilities.php</filename> - required if you
          want to render your XML as a normalized (whitespace formatted)
          string or if you want to use the parseXML method of
          DOMIT_Lite_Document.</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_getelementsbypath.php</filename> -
          required if you would like to search for elements in your
          DOMIT_Lite_Document using a path-based syntax.</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_nodemaps.php</filename> - data structures
          that contain collections of nodes</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_cache.php</filename> - simple caching
          class for DOMIT! and DOMIT! Lite documents</para>
        </listitem>

        <listitem>
          <para><filename>xml_saxy_lite_parser.php</filename> - required if
          you would like to use the SAXY Lite parser with DOMIT! Lite instead
          of the Expat parser.</para>
        </listitem>

        <listitem>
          <para><filename>xml_domit_doctor.php</filename> - class for
          repairing malformed xml</para>
        </listitem>

        <listitem>
          <para><filename>php_file_utilities.php</filename> - generic file
          input / output utilities</para>
        </listitem>

        <listitem>
          <para><filename>php_http_client.php</filename> - generic http client
          class</para>
        </listitem>

        <listitem>
          <para><filename>php_http_client_include.php</filename> - include
          file for http client class</para>
        </listitem>

        <listitem>
          <para><filename>php_http_connector.php</filename> - helper class for
          php_http_client</para>
        </listitem>

        <listitem>
          <para><filename>php_http_exceptions.php</filename> - http exceptions
          class</para>
        </listitem>

        <listitem>
          <para><filename>php_http_proxy.php</filename> - http proxy
          class</para>
        </listitem>
      </itemizedlist>
    </section>

    <section>
      <title>Including the DOMIT! Library in your Scripts</title>

      <para>To implement DOMIT! in your PHP scripts, include the file
      <filename>xml_domit_include.php</filename>:</para>

      <para><programlisting>require_once('somepath/xml_domit_include.php');</programlisting></para>

      <para>To implement DOMIT! Lite in your PHP scripts, include the file
      <filename>xml_domit_lite_include.php</filename>:</para>

      <para><programlisting>require_once('somepath/xml_domit_lite_include.php');</programlisting></para>
    </section>
  </chapter>

  <chapter>
    <title>Loading a DOMIT_Document</title>

    <section>
      <title>Instantiating and Populating a DOMIT_Document</title>

      <para>In DOMIT!, a DOM Document is represented by the DOMIT_Document
      class.</para>

      <section>
        <title>Instantiating a DOMIT_Document</title>

        <para>You create an instance of the DOMIT_Document class in the same
        way as any other PHP class:</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document();</programlisting>

        <para>A DOMIT! Lite document is instantiated like this:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Lite_Document();</programlisting></para>

        <para>Once a document has been instantiated, it is ready to be
        populated with XML data.</para>

        <para><remark>Note: to ensure PHP 4 backwards compatability, it is
        necessary to include an ampersand (&amp;) symbol after the equal sign
        when returning a reference to a DOMIT_Document or any other DOMIT!
        object.</remark></para>
      </section>

      <section>
        <title><function>parseXML</function>: Populating a DOMIT_Document from
        a string variable</title>

        <para>If we wanted to create a DOMIT_Document out of a PHP string, we
        would use the <function>parseXML</function> method. Take for instance,
        the cd collection XML described in the previous section:</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document(); //instantiate document

//create string variable with XML text
$cdCollectionString = "&lt;?xml version="1.0"?&gt;&lt;cdlibrary&gt;&lt;cd discid=\"bb0c3c0c\"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;&lt;/cd&gt;
  &lt;cd discid=\"9b0ce70c\"&gt;&lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;&lt;/cd&gt;&lt;cd discid=\"cf11720f\"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  &lt;title&gt;Laugh&lt;/title&gt;&lt;/cd&gt;
  &lt;/cdlibrary&gt;";

//use parseXML method to populate document
$success = $cdCollection-&gt;parseXML($cdCollectionString, true); //parse document</programlisting>

        <para><computeroutput><function>parseXML</function></computeroutput>
        returns <emphasis role="bold">true</emphasis> if the parsing is
        successful</para>
      </section>

      <section>
        <title><function>loadXML</function>: Populating a DOMIT_Document from
        a file or url</title>

        <para>The <function>loadXML</function> method of DOMIT_Document is
        used to load an XML string from a file or url. It uses an identical
        syntax to the <function>parseXML</function> method:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");</programlisting></para>

        <para>The above example parses a file from the file system.</para>

        <para>To parse an url, you would specify the full HTTP address as the
        first parameter:<programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("http://www.engageinteractive.com/rssfeed.xml");</programlisting></para>
      </section>

      <section>
        <title><function>useSAXY</function>: Specifiying a SAX parser</title>

        <para>DOMIT! relies on an underlying SAX parser to parse XML data. You
        have the choice of one of two SAX parsers:</para>

        <itemizedlist>
          <listitem>
            <para><ulink url="http://www.php.net/xml">Expat</ulink> is a
            C-based SAX parser written by James Clark that comes bundled with
            most later distributions of PHP.</para>
          </listitem>

          <listitem>
            <para><ulink
            url="http://www.engageinteractive.com/saxy/">SAXY</ulink> is a
            pure PHP SAX parser written by <ulink
            url="http://www.engageinteractive.com/">Engage Interactive</ulink>
            that comes bundled with DOMIT!</para>
          </listitem>
        </itemizedlist>

        <para>The second parameter of both <function>parseXML</function> and
        <function>loadXML</function> allows you to specify a SAX parser. The
        <function>useSAXY</function> parameter is a boolean whose default
        value is <emphasis>true</emphasis>. Specifying false will check
        whether Expat is available and use it to parse and pass the XML data
        to DOMIT!:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml", false); //Expat specified</programlisting></para>

        <para>If Expat cannot be detected, DOMIT! will revert to SAXY for its
        parsing.</para>
      </section>

      <section>
        <title>Determining the base SAX parser</title>

        <para>To determine whether Expat or SAXY was used to generate a
        DOMIT_Document, you can use the <function>parsedBy
        </function>method:<programlisting>$saxParser = $xmldoc-&gt;parsedBy();</programlisting></para>

        <para>The parsedBy method returns a string with a value of either
        <emphasis>EXPAT</emphasis> or <emphasis>SAXY</emphasis>.</para>
      </section>
    </section>

    <section>
      <title>Optional Settings for Loading XML Data</title>

      <para>Sometimes the default DOMIT! mechanism for populating a
      DOMIT!_Document is insufficient. This is particularly true when
      retrieving XML data from a remote location.</para>

      <para>By default, DOMIT! uses the PHP function
      <function>get_file_contents</function> or standard PHP file input
      streams to retrieve the contents of an XML file. However, both of these
      approaches can fail when passed a remote URL as the location of the XML
      file to parsed.</para>

      <para>A number of additional options exist to deal with these
      possibilities.</para>

      <section>
        <title><function>useHTTPClient:</function> Forcing loadXML to use an
        HTTP Client</title>

        <para>As of version 1.0, DOMIT! comes bundled with the
        <computeroutput>php_http_client</computeroutput> library, written by
        <ulink url="http://www.engageinteractive.com/">Engage
        Interactive</ulink>. With the <function>useHTTPClient</function>
        method, DOMIT! can be forced to establish a standard HTTP connection
        to the web server hosting the XML file:<programlisting>$cdCollection =&amp; new DOMIT_Document();

//specify that an HTTP client should be used to retrieve XML
$xmldoc-&gt;useHTTPClient(true); 

//call loadXML method as usual
$success = $cdCollection-&gt;loadXML("http://www.engageinteractive.com/rssfeed.xml", false); </programlisting></para>

        <para>The HTTP connection will be attempted on port 80.</para>
      </section>

      <section>
        <title><function>setConnection</function>: Manually specifying HTTP
        connection parameters</title>

        <para>If you need to establish an HTTP connection to retrieve your XML
        data, but the <function>useHTTPClient</function> method does not
        provide enough flexibility, the <function>setConnection</function>
        method of DOMIT_Document can be used to manually set the parameters of
        the connection.</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document();
$xmldoc-&gt;setConnection('http://www.engageinteractive.com', '/', '955');

//call loadXML method as usual
$success = $cdCollection-&gt;loadXML("http://www.engageinteractive.com/rssfeed.xml", false);</programlisting>

        <para>In the above example, an HTTP connection will be established on
        port 955 of host
        <emphasis>http://www.engageinteractive.com</emphasis>. You can also
        use a raw IP address for the host, such as
        <emphasis>http://198.162.0.10</emphasis></para>

        <para>Note that you can also pass in a user name and password to the
        <function>setConnection</function> method, if you must use HTTP
        Authorization to establish your connection. For more about HTTP
        Authorization, please see the entry on the
        <function>setAuthorization</function> method.</para>
      </section>

      <section>
        <title><function>setAuthorization</function>: Using basic HTTP
        authorization with your connection</title>

        <para>The HTTP specification allows for a basic (i.e., not
        particularly secure) type of authorization called <emphasis>HTTP
        Authorization</emphasis>. If the XML file that you require is
        protected by this sort of authentication, you can use the
        <function>setAuthorization</function> method of DOMIT!.
        <function></function></para>

        <para><function>setAuthorization</function> is used in conjunction
        with the <function>setConnection</function> method, and requires that
        you provide a plain text username and password:</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document();
$xmldoc-&gt;setConnection('http://www.engageinteractive.com', '/', '955');
$xmldoc-&gt;setAuthorization('johnheinstein', 'mypassword');

//call loadXML method as usual
$success = $cdCollection-&gt;loadXML("http://www.engageinteractive.com/rssfeed.xml", false);</programlisting>
      </section>

      <section>
        <title><function>setProxyConnection</function>: Retrieving XML data
        through a proxy server</title>

        <para>An <emphasis>HTTP proxy</emphasis> is a server that acts as an
        intermediary between an HTTP client (a user's browser) and the
        Internet. It is used to enforce security, administrative control, and
        caching services. If you are behind a firewall, for instance, and must
        connect to a proxy server to access web based resources, then the
        <function>setProxyConnection</function> method will allow you to
        access such data.</para>

        <para>The <function>setProxyConnection</function> method works inn
        exactly the same way as <function>setConnection</function>:</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document();
$xmldoc-&gt;setProxyConnection('http://www.myproxyconnection.com', '/', '1060');

//call loadXML method as usual
$success = $cdCollection-&gt;loadXML("http://www.engageinteractive.com/rssfeed.xml", false);</programlisting>
      </section>

      <section>
        <title><function>setProxyAuthorization</function>: Using basic HTTP
        authorization with your proxy</title>

        <para>The <function>setProxyAuthorization</function> is called in
        exactly the same way as <function>setAuthorization</function>. Just
        provide a valid user name and password:</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document();
$xmldoc-&gt;setProxyConnection('http://www.myproxyconnection.com', '/', '1060');
$xmldoc-&gt;setProxyAuthorization('johnheinstein', 'mypassword');

//call loadXML method as usual
$success = $cdCollection-&gt;loadXML("http://www.engageinteractive.com/rssfeed.xml", false);</programlisting>
      </section>

      <section>
        <title><function>preserveWhiteSpace</function></title>

        <para>By default, when loading an XML document, DOMIT! removes what it
        considers insignificant whitespace -- such as the tabs between XML
        tags that are used for formatting purposes only.</para>

        <para>Whitespace can be retained, however, if the following is called
        prior to loading or parsing:</para>

        <para><programlisting>$cdCollection-&gt;preserveWhitespace(true);</programlisting></para>
      </section>

      <section>
        <title><function>appendEntityTranslationTable</function></title>

        <para>When DOMIT! parses or loads an XML Document, often entities are
        present which must be transformed into their corresponding character
        representations. Generally it is the responsibility of the DOCTYPE
        declaration to delineate these conversions.</para>

        <para>However, DOMIT! is a non-validating parser, and is unaware of
        constraints placed on a document by the DOCTYPE.</para>

        <para>The <function>appendEntityTranslationTable</function> method is
        an alternate way of specifying character equivalents of
        entities.</para>

        <para>It takes a single parameter -- an associative array of entities
        mapped to their equivalent characters. For example, if one wanted to
        instruct DOMIT! to convert all
        <computeroutput>&amp;copy;</computeroutput> entities into
        <computeroutput>©</computeroutput> :</para>

        <para><programlisting>//create translation table
$myTranslationTable = array('&amp;copy;' =&gt; '©');

//pass table to document
$cdCollection-&gt;appendEntityTranslationTable($myTranslationTable);</programlisting></para>

        <para></para>
      </section>
    </section>

    <section>
      <title>Error Handling During and After Loading an XML Document</title>

      <para>When DOMIT! parses XML from a string or loads XML from a file,
      several methods can be used to handle non-conformant XML and retrieve
      error codes.</para>

      <para>DOMIT! also allows you to set a custom error handler for runtime
      XML processing errors.</para>

      <section>
        <title><function>resolveErrors</function></title>

        <para>If the <function>resolveErrors</function> method is called,
        DOMIT! will attempt to locate and fix any problems with improperly
        formatted XML code. The method must be called before parsing begins;
        just pass it a value of <emphasis role="bold">true</emphasis>:</para>

        <programlisting>$cdCollection =&amp; new DOMIT_Document();
$cdCollection-&gt;resolveErrors(true);
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");</programlisting>

        <para>Note that <function>resolveErrors</function> may have an impact
        on speed, and should be used judiciously.</para>

        <para>Currently, <function>resolveErrors</function> only searches for
        and replaces ampersands that have not been encoded as
        <computeroutput>&amp;amp;</computeroutput></para>
      </section>

      <section>
        <title><function>getErrorCode</function> and
        <function>getErrorString</function></title>

        <para>If <function>loadXML</function> or <function>parseXML</function>
        return false, an error has occurred in processing. The methods
        <function>getErrorCode</function> and
        <function>getErrorString</function> can be used to diagnose where the
        problem lies.</para>

        <para><function>getErrorCode</function> returns a numerical
        description of the error, and <function>getErrorString</function>
        returns a textual description of the error. For example:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$cdCollection-&gt;resolveErrors(true);
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //process XML
}
else {
  //an error has occurred; echo to browser
  echo "Error code: " . $cdCollection-&gt;getErrorCode();
  echo "\n&lt;br /&gt;";
  echo "Error string: " . $cdCollection-&gt;getErrorString();
}</programlisting></para>
      </section>

      <section>
        <title>DOMIT_DOMException::setErrorHandler</title>

        <para>If you would like to set a custom error handler for DOMIT! to
        handle runtime XML processing errors, you can use a static method of
        the <function>DOMIT_DOMException</function> class:
        <function>setErrorHandler</function>.</para>

        <para>It takes a single parameter -- the method to handle the
        error.</para>

        <para>The custom errorhandler method must have the following method
        signature...</para>

        <para><computeroutput>function myCustomErrorHandler($errorNum,
        $errorString) </computeroutput></para>

        <para>...where <computeroutput>$errorNum</computeroutput> is an
        integer signifying the number of the error, and
        <function>$errorString</function> is a string giving a description of
        the error.</para>

        <para>For example, if you wrote a function to handle your DOMIT!
        errors that looked like this:</para>

        <para><programlisting>function myErrorHandler($errorNum, $errorString) {
  echo "The error number is " . $errorNum . " and " the error string is " . $errorString;
}</programlisting></para>

        <para>You could invoke it like this:</para>

        <para><programlisting>DOMIT_DOMException::setErrorHandler("myErrorHandler");</programlisting></para>

        <para>If the <function>myErrorHandler</function> function was a method
        of a class named <function>ErrorHandlers</function> rather than a
        standalone function, you could invoke setErrorHandler like
        this:</para>

        <para><programlisting>DOMIT_DOMException::setErrorHandler(array("ErrorHandlers", "myErrorHandler"));</programlisting></para>
      </section>

      <section>
        <title><function>DOMIT_DOMException::setErrorMode</function></title>

        <para>The <function>DOMIT_DOMException::setErrorMode</function> method
        allows you to define the behavior of DOMIT! when an exception occurs.
        It takes a single parameter -- an integer or interger constant
        representing the error mode:</para>

        <itemizedlist>
          <listitem>
            <para><emphasis role="bold">DOMIT_ONERROR_CONTINUE</emphasis> (1)
            - specifies that DOMIT! should continue processing after an
            exception occurs. This is the default behavior.</para>
          </listitem>

          <listitem>
            <para><emphasis role="bold">DOMIT_ONERROR_DIE</emphasis> (2) -
            specifies that DOMIT! should die and display the error message
            after an exception occurs.</para>
          </listitem>
        </itemizedlist>

        <para>For example:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();

//sets DOMIT! to die on an exception
DOMIT_DOMException::setErrorMode(DOMIT_ONERROR_DIE);</programlisting></para>
      </section>

      <section>
        <title><function>DOMIT_DOMException::setErrorLog</function></title>

        <para>The <function>DOMIT_DOMException::setErrorLog</function> method
        allows you to specify a file to which error messages are logged and
        timestamped. This is a useful feature for debugging XML parsing
        problems.</para>

        <para>It takes two parameters:</para>

        <itemizedlist>
          <listitem>
            <para>a boolean specifying whether logging should be turned on
            (true) or off (false)</para>
          </listitem>

          <listitem>
            <para>a string containing the absolute or relative path of the
            error log file.</para>
          </listitem>
        </itemizedlist>

        <para>The following example specifies that errors are to be logged to
        the file 'errorLog.txt':</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();

//specifies that error logging is to be enabled and the error log filename
DOMIT_DOMException::setErrorLog(true, 'errorLog.txt');</programlisting></para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>Traversing a Document and Extracting Data</title>

    <para>Once a DOMIT_Document has been populated, you can use the standard
    DOM methods to extract and manipulate data in the XML tree. The following
    chapter illustrates how this can be done.</para>

    <section>
      <title>The Document Element Node</title>

      <para>You can acquire a reference to the document element node -- the
      root element in a DOM document -- using the<function>
      documentElement</function> keyword.</para>

      <programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //gets a reference to the root element of the cd collection
  $myDocumentElement =&amp; $cdCollection-&gt;documentElement;
}</programlisting>

      <para>In the cd library example, the document element node is the node
      <computeroutput>&lt;cdlibrary&gt;</computeroutput> .</para>

      <para><remark>Note: Always remember to use the reference (&amp;)
      operator in PHP4, or you will be returned a shallow copy of the
      childNodes array. Even if you are using PHP5, it is recommended for the
      sake of portability to other web servers that you use an ampersand
      anyway.</remark></para>
    </section>

    <section>
      <title>Displaying a Node as Text</title>

      <para>A text representation of a node and its contents can be displayed
      using the <computeroutput><function>toString</function></computeroutput>
      and
      <computeroutput><function>toNormalizedString</function></computeroutput>
      methods. The <function>expandEmptyElementTags</function> method can be
      used to further tweak your output.</para>

      <section>
        <title><function>toString</function></title>

        <para>Take the document element node of the cd library example above.
        Once a reference to the
        <computeroutput>&lt;cdlibrary&gt;</computeroutput> node has been
        obtained using the <function>documentElement</function> keyword, we
        can see what it contains:</para>

        <programlisting>$myDocumentElement =&amp; $cdCollection-&gt;documentElement;
echo $myDocumentElement-&gt;toString(true);</programlisting>

        <para>The following string will be echoed to the browser
        window:</para>

        <programlisting>&lt;cdlibrary&gt;&lt;cd discid="bb0c3c0c"&gt;&lt;name&gt;Robbie Fulks&lt;/name&gt;&lt;title&gt;Couples in Trouble&lt;/title&gt;&lt;/cd&gt;&lt;cd discid="9b0ce70c"&gt;&lt;name&gt;Richard Thompson&lt;/name&gt;&lt;title&gt;Mock Tudor&lt;/title&gt;&lt;/cd&gt;&lt;cd discid="cf11720f"&gt;&lt;name&gt;Keller Williams&lt;/name&gt;&lt;title&gt;Laugh&lt;/title&gt;&lt;/cd&gt;&lt;/cdlibrary&gt;</programlisting>

        <para>The first parameter of <function>toString</function> , if set to
        <emphasis role="bold">true</emphasis>, converts special HTML
        characters into their encoded version (i.e. <emphasis>&amp;</emphasis>
        into <emphasis>&amp;amp;</emphasis>) so that they will display
        properly in a browser.</para>

        <para>If you would like unconverted raw text to be output (for
        instance, when echoing to a command line interface) substitute a value
        of <emphasis role="bold">false</emphasis>:</para>

        <para><programlisting>echo $myDocumentElement-&gt;toString(false);</programlisting></para>
      </section>

      <section>
        <title><function>toNormalizedString</function></title>

        <para>One drawback of the <function>toString</function> output is that
        it is not particularly readable, since all text of the node is
        compressed into one line. The <function>toNormalizedString</function>
        method will output text that is much more nicely formatted:</para>

        <programlisting>$myDocumentElement =&amp; $cdCollection-&gt;documentElement;
echo $myDocumentElement-&gt;toNormalizedString(true);</programlisting>

        <para>The following string will be echoed to the browser
        window:</para>

        <programlisting>&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>

        <para>As with the <function>toString</function> method, passing a
        value of <emphasis role="bold">false</emphasis> into
        <function>toNormalizedString</function> outputs text that is not
        formatted for HTML display.</para>
      </section>

      <section>
        <title>expandEmptyElementTags</title>

        <para>When outputting XML using <function>toString</function> or
        <function>toNormalized</function> string, by default DOMIT! represents
        empty elements using the abbreviated convention:</para>

        <para><programlisting>&lt;anEmptyElement /&gt;</programlisting></para>

        <para>If you prefer the tags to be expanded instead, use the
        expandEmptyElementTags method:</para>

        <para><programlisting>$xmldoc-&gt;expandEmptyElementTags(true);</programlisting></para>

        <para>When using DOMIT! to render XHTML documents, often it is
        necessary to leave some tags unexpanded, such as the
        <computeroutput>&lt;br /&gt;</computeroutput> tag. The
        <function>expandEmptyElementTags</function> method allows you to pass
        in an array of exceptions to the expansion rule:</para>

        <para><programlisting>//create array of exceptions to the empty element expansion rule
$expansionExceptions = array('br', 'hr');

//invoke expansion rule, passing in array of exceptions as second parameter
$xmldoc-&gt;expandEmptyElementTags(true, $expansionExceptions);</programlisting></para>

        <para>This might result in output that looked like this:</para>

        <para><programlisting>&lt;html&gt;
  &lt;body&gt;
    &lt;p&gt;This is a test&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
    &lt;br /&gt;
  &lt;/body&gt;
&lt;/html&gt;</programlisting></para>

        <para></para>
      </section>
    </section>

    <section>
      <title>Obtaining Node Type, Name, and Value</title>

      <para>In an earlier section, we learned that each node in a DOM document
      has three properties -- node type, node name, and node value -- that
      allows you to distinguish between it and other nodes.</para>

      <para>These properties are accessible in DOMIT! with the
      <function>nodeType</function>, <function>nodeName</function>, and
      <function>nodeValue</function> keywords.</para>

      <para>To echo out these properties for the document element of the
      cdlibrary example, for instance, you would do this:</para>

      <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //gets a reference to the root element of the cd collection
  $myDocumentElement =&amp; $cdCollection-&gt;documentElement;

  //echo out node name
  echo "Node name: " . $myDocumentElement-&gt;nodeName;
  echo "\n&lt;br /&gt;";

  //echo out node type
  echo "Node type: " . $myDocumentElement-&gt;nodeType;
  echo "\n&lt;br /&gt;";

  //echo out node value
  echo "Node value: " . $myDocumentElement-&gt;nodeValue;
  echo "\n&lt;br /&gt;";
}</programlisting></para>

      <para>The above example would display:</para>

      <para><programlisting>cdlibrary
1
 </programlisting></para>

      <para>Note that the last line is blank because the node value for an
      element is <emphasis role="bold">null</emphasis>.</para>
    </section>

    <section>
      <title>Traversing a DOM Tree</title>

      <para>You know how to:</para>

      <itemizedlist>
        <listitem>
          <para>instantiate a DOMIT! document</para>
        </listitem>

        <listitem>
          <para>populate a DOMIT! document using the
          <computeroutput>loadXML</computeroutput> or
          <computeroutput>parseXML</computeroutput> methods</para>
        </listitem>

        <listitem>
          <para>obtain a reference to the document element</para>
        </listitem>

        <listitem>
          <para>print the contents of a node, and</para>
        </listitem>

        <listitem>
          <para>display the three basic node properties</para>
        </listitem>
      </itemizedlist>

      <para>We will now learn how to access other parts of a document using
      such DOM constructs as child nodes, parent nodes, and next and previous
      siblings.</para>

      <section>
        <title>The
        <computeroutput><function>childNodes</function></computeroutput>
        array,
        <computeroutput><function>hasChildNodes</function></computeroutput>,
        and
        <computeroutput><function>childCount</function></computeroutput></title>

        <para>As explained previously, each node in a DOM Document has a list
        of references to the nodes contained directly beneath it in the tree:
        its <emphasis>Child Nodes</emphasis>.</para>

        <para>In DOMIT!, the child nodes exist as a standard PHP array named
        <computeroutput><function>childNodes</function></computeroutput>.</para>

        <para>To grab a reference to the <function>childNodes</function> array
        of a node, use the following syntax:</para>

        <programlisting>//get a reference to the childNodes collection of the document element
$myChildNodes =&amp; $cdCollection-&gt;documentElement-&gt;childNodes;</programlisting>

        <para><remark>Note: When returning areference to the childNodes array
        in PHP4, always remember to use the reference (&amp;) operator, or you
        will be returned a shallow copy.</remark></para>

        <para>It is good practice, prior to grabbing a reference to the
        <function>childNodes</function> array, to use the
        <function>hasChildNodes</function> method to check if any child nodes
        exist:</para>

        <programlisting>//ensure that there are childNodes before bothering to work with the childNodes array
if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {
  $myChildNodes =&amp; $cdCollection-&gt;documentElement-&gt;childNodes;
}</programlisting>

        <para>The number of child nodes is stored in the
        <computeroutput><function>childCount</function></computeroutput>
        property. You can use this value to traverse the
        <function>childNodes</function> array and access its individual
        nodes:</para>

        <programlisting>//ensure that there are childNodes before bothering to work with the childNodes array
if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get a reference to the childNodes collection of the document element
  $myChildNodes =&amp; $cdCollection-&gt;documentElement-&gt;childNodes;

  //get the total number of childNodes for the document element
  $numChildren =&amp; $cdCollection-&gt;documentElement-&gt;childCount;

  //iterate through the collection
  for ($i = 0; $i &lt; $numChildren; $i++) {

    //get a reference to the i childNode
    $currentNode =&amp; myChildNodes[$i];
    
    //echo out the node to browser
    echo ("Node $i contents are: \n&lt;br /&gt;" . 
      $currentNode-&gt;toNormalizedString(true) . "\n&lt;br /&gt;\n&lt;br /&gt;");
  }
}</programlisting>

        <para>The above example will return:</para>

        <programlisting>Node 1 contents are:
&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;

Node 2 contents are:
&lt;cd discid="9b0ce70c"&gt;
  &lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;/cd&gt;

Node 3 contents are:
&lt;cd discid="cf11720f"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  &lt;title&gt;Laugh&lt;/title&gt;
&lt;/cd&gt;</programlisting>
      </section>

      <section>
        <title><computeroutput><function>firstChild</function></computeroutput></title>

        <para>The
        <computeroutput><function>childNodes</function></computeroutput> array
        is not the only means of accessing the children of a node.</para>

        <para>The
        <computeroutput><function>firstChild</function></computeroutput>
        property of a node returns a reference to a node's
        <emphasis>first</emphasis> child node:</para>

        <programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first child node of document element
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //echo out the node to browser
  echo ("The contents of the first child node are: \n&lt;br /&gt;" . 
      $firstChildNode-&gt;toNormalizedString(true));
  }
}</programlisting>

        <para>The above example will return:</para>

        <programlisting>The contents of the first child node are:
&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;</programlisting>

        <para><remark>Note: If there are no child nodes present, a value of
        <emphasis role="bold">null</emphasis> is returned.</remark></para>
      </section>

      <section>
        <title><function>lastChild</function></title>

        <para>The
        <computeroutput><function>lastChild</function></computeroutput>
        property of a node returns a reference to a node's
        <emphasis>last</emphasis> child node:</para>

        <programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to last child node
  $lastChildNode =&amp; $cdCollection-&gt;documentElement-&gt;lastChild;

  //echo out the node to browser
  echo ("The contents of the last child node are: \n&lt;br /&gt;" . 
      $lastChildNode-&gt;toNormalizedString(true));
  }
}</programlisting>

        <para>The above example will return:</para>

        <programlisting>The contents of the last child node are:
&lt;cd discid="cf11720f"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  &lt;title&gt;Laugh&lt;/title&gt;
&lt;/cd&gt;</programlisting>

        <para>If there are no child nodes present, a value of <emphasis
        role="bold">null</emphasis> is returned.</para>
      </section>

      <section>
        <title><function>nextSibling</function></title>

        <para>Nodes that occupy the same level of a DOM tree are called
        <emphasis>siblings</emphasis>. The DOM conceives of these nodes as
        being chained in a sequence, with each node aware of the node
        immediately preceding and immediately following it.</para>

        <para>The
        <computeroutput><function>nextSibling</function></computeroutput>
        property of a node returns a reference to the node
        <emphasis>prior</emphasis> to it in the sibling chain.</para>

        <para>In the cdlibrary example, the next sibling of the Robbie Fulks
        <computeroutput>&lt;cd&gt;</computeroutput> node is the Richard
        Thompson <computeroutput>&lt;cd&gt;</computeroutput> node. One would
        access it like this:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //get a reference to the next sibling (the Richard Thompson cd)
  $nextSiblingNode =&amp; $firstChildNode-&gt;nextSibling;

  //echo out the node to browser
  echo ("The contents of the next sibling are: \n&lt;br /&gt;" . 
      $nextSiblingNode-&gt;toNormalizedString(true));
  }
}</programlisting></para>

        <para>The above example will return:</para>

        <programlisting>The contents of the next sibling are:
&lt;cd discid="9b0ce70c"&gt;
  &lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;/cd&gt;</programlisting>

        <para>If there are no next sibling nodes present, a value of <emphasis
        role="bold">null</emphasis> is returned.</para>
      </section>

      <section>
        <title><function>previousSibling</function></title>

        <para>The
        <computeroutput><function>lastSibling</function></computeroutput>
        property of a node returns a reference to the node
        <emphasis>after</emphasis> it in the sibling chain.</para>

        <para>In the cdlibrary example, the previous sibling of the Keller
        Williams <computeroutput>&lt;cd&gt;</computeroutput> node is the
        Richard Thompson <computeroutput>&lt;cd&gt;</computeroutput> node. One
        would access it like this:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to last cd node (the Keller Williams cd)
  $lastChildNode =&amp; $cdCollection-&gt;documentElement-&gt;lastChild;

  //get a reference to the previous sibling (the Richard Thompson cd)
  $previousSiblingNode =&amp; $lastChildNode-&gt;previousSibling;

  //echo out the node to browser
  echo ("The contents of the previous sibling are: \n&lt;br /&gt;" . 
      $previousSiblingNode-&gt;toNormalizedString(true));
  }
}</programlisting></para>

        <para>The above example will return:</para>

        <programlisting>The contents of the previous sibling are:
&lt;cd discid="9b0ce70c"&gt;
  &lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;/cd&gt;</programlisting>

        <para>If there are no previous sibling nodes present, a value of
        <emphasis role="bold">null</emphasis> is returned.</para>
      </section>

      <section>
        <title><function>parentNode</function></title>

        <para>As the name implies, the
        <computeroutput><function>parentNode</function></computeroutput>
        property of a node returns a reference to the node <emphasis>one level
        above it</emphasis> in the DOM tree.</para>

        <para>In the cdlibrary example, the parent node of the Robbie Fulks
        <computeroutput>&lt;cd&gt;</computeroutput> node is the document
        element <computeroutput>&lt;cdlibrary&gt;</computeroutput> node. One
        would access it like this:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //get a reference to the parent (cdlibrary) node
  $myParentNode =&amp; $firstChildNode-&gt;parentNode;

  //echo out the node to browser
  echo ("The contents of the parent node of the Robbie Fulks cd node are: \n&lt;br /&gt;" . 
      $myParentNode-&gt;toNormalizedString(true));
  }
}</programlisting></para>

        <para>The above example will return:</para>

        <programlisting>The contents of the parent node of the Robbie Fulks cd node are:
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>

        <para>If there is no parent node present, a value of <emphasis
        role="bold">null</emphasis> is returned. Note that only the document
        element node will have no parent.</para>
      </section>

      <section>
        <title><function>ownerDocument</function></title>

        <para>Each node in a DOM document -- with the the exception of
        attribute nodes -- is considered to be "owned" by that
        document.</para>

        <para>Use the <function>ownerDocument</function> property of a node to
        obtain a reference to the DOMIT! document:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //get a reference to the DOMIT document
  $myOwnerDocument =&amp; $firstChildNode-&gt;ownerDocument;
}</programlisting></para>
      </section>
    </section>

    <section>
      <title>Extracting Character Data</title>

      <para>Text nodes, CDATA Section nodes, and comment nodes belong to what
      is defined by the DOM as the CharacterData interface, which specifies a
      number of methods for obtaining the textual data. The following section
      describes some of these methods.</para>

      <section>
        <title>nodeValue</title>

        <para>The easiest way of getting the data from a text node, CDATA
        Section nodes, or comment node is through its
        <function>nodeValue</function> property.</para>

        <para><remark>Note: A common error that many DOM newbies make is to
        confuse a text node with the element node that contains it. It is
        important to realize that a text node is always the
        <emphasis>child</emphasis> of the containing element. </remark></para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //get a reference to the &lt;name&gt; element of the Robbie Fulks cd
  $nameElement =&amp; $cdCollection-&gt;documentElement-&gt;childNodes[0]-&gt;firstChild;

  //get a reference to the text node
  //(this step has been broken into multiple steps to emphasize that
  //a text node must be distinguished from its containing element!)
  $nameTextNode =&amp; $nameElement-&gt;firstChild;

  //echo out the data in the text node 
  echo $nameTextNode-&gt;nodeName;
}</programlisting></para>

        <para>The above example returns:</para>

        <para><programlisting>Robbie Fulks</programlisting></para>

        <para>If you prefer, you can condense the above steps into a single
        line:</para>

        <para><programlisting>$myText  = $cdCollection-&gt;documentElement-&gt;childNodes[0]-&gt;firstChild-&gt;firstChild-&gt;nodeName;</programlisting></para>
      </section>

      <section>
        <title>getData</title>

        <para>The <function>getData</function> method is a wrapper for the
        <function>nodeValue</function> keyword and functions in exactly the
        same way:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //get a reference to the &lt;name&gt; element of the Robbie Fulks cd
  $nameElement =&amp; $cdCollection-&gt;documentElement-&gt;childNodes[0]-&gt;firstChild;

  //get a reference to the text node
  //(this step has been broken into multiple steps to emphasize that
  //a text node must be distinguished from its containing element!)
  $nameTextNode =&amp; $nameElement-&gt;firstChild;

  //echo out the data in the text node 
  echo $nameTextNode-&gt;getData();
}</programlisting></para>
      </section>

      <section>
        <title>getText</title>

        <para>In most cases, the <function>getText</function> method functions
        identically to <function>nodeValue</function> and
        <function>getData</function>. You can simply substitute the word
        <emphasis>getText</emphasis> for the word <emphasis>getData</emphasis>
        in the previous example and the results will be the same.</para>

        <para>However, <function>getText</function> can also be called on an
        <emphasis>element</emphasis>. In this case, the concatenated text of
        <emphasis>all children beneath the element</emphasis> is returned. For
        instance:</para>

        <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //get a reference to the Robbie Fulks &lt;cd&gt; element
  $cdElement =&amp; $cdCollection-&gt;documentElement-&gt;childNodes[0];

  //get ALL text beneath the cd element ("name" text + "title" text)
  $childText = $cdElement-&gt;getText();

  //echo out the concatenated data 
  echo childText;
}</programlisting></para>

        <para>The above example returns:</para>

        <para><programlisting>Robbie FulksCouples in Trouble</programlisting></para>
      </section>

      <section>
        <title>getLength</title>

        <para>The <function>getLength</function> method indicates how many
        characters exist in a character data node:</para>

        <para><programlisting>$numCharacters = $myTexNode-&gt;getLength();</programlisting></para>
      </section>

      <section>
        <title>substringData</title>

        <para>The substringData method returns a specified subset of
        characters from a character data node.</para>

        <para>It takes two parameters:</para>

        <itemizedlist>
          <listitem>
            <para><emphasis role="bold">offset</emphasis>: an integer
            specifying the starting character of the substring</para>
          </listitem>

          <listitem>
            <para><emphasis role="bold">count</emphasis>: an integer
            specifying how many characters from the offset should be included
            in the substring</para>
          </listitem>
        </itemizedlist>

        <para>To extract the first name from the "Robbie Fulks" text node, for
        example, one would do this:</para>

        <para><programlisting>$firstName = $rfTextNode-&gt;substringData(0,6);</programlisting></para>
      </section>
    </section>

    <section>
      <title>Accessing Attributes</title>

      <para>In a DOM document, attributes are accessed, by name, from their
      containing element. The DOMIT! methods <function>hasAttribute</function>
      and <function>getAttribute</function> can be used to extract attribute
      data.</para>

      <section>
        <title><function>hasAttribute</function></title>

        <para>To determine whether an element contains a particular attribute,
        you can use the <function>hasAttribute</function> method. It takes a
        single string parameter -- the name of the attribute -- and returns
        either <emphasis role="bold">true</emphasis> or <emphasis
        role="bold">false</emphasis>:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //determine whether it has an attribute named "discid" 
  if ($firstChildNode-&gt;hasAttribute("discid")) {
    echo ("I DO have a discid attribute");
  }
  else {
    echo ("I DO NOT have a discid attribute");
  }
}</programlisting></para>
      </section>

      <section>
        <title><function>hasAttributes</function></title>

        <para>The <function>hasAttributes</function> method returns true if an
        element contains at least one attribute.</para>

        <para><programlisting>if ($someNode-&gt;hasAttributes()) {
    echo ("I have at least one attribute");
  }
  else {
    echo ("I have no attributes");
  }</programlisting></para>
      </section>

      <section>
        <title><function>getAttribute</function></title>

        <para>To obtain the value of a named attribute, use the
        <function>getAttribute</function> method. As with the
        <function>hasAttribute</function> method, you pass in the attribute
        name:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //determine whether it has an attribute named "discid" 
  if ($firstChildNode-&gt;hasAttribute("discid")) {

    //obtain the value of the discid attribute
    $attrValue = $firstChildNode-&gt;getAttribute("discid);

    //echo the value out to the browser
    echo ("Attribute value: " . $attrValue);
  }
  else {
    echo ("I DO NOT have a discid attribute");
  }
}</programlisting></para>

        <para>The above example returns:</para>

        <para><programlisting>bb0c3c0c</programlisting></para>

        <para><remark>Note: If the attribute does not exist, an empty string
        (i.e., "") is returned.</remark></para>
      </section>

      <section>
        <title><function>getAttributeNode</function> and
        <function>getValue</function></title>

        <para>The getAttribute method returns the <emphasis>value</emphasis>
        of an attribute node. If you would like to obtain a
        <emphasis>reference to the node itself</emphasis>, use the
        <function>getAttributeNode</function> method.</para>

        <para>To obtain the value of an attribute node, use either the
        <function>getValue</function> method:</para>

        <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //determine whether it has an attribute named "discid" 
  if ($firstChildNode-&gt;hasAttribute("discid")) {

    //obtain a reference to the discid attribute node (don't forget the ampersand!)
    $attrNode =&amp; $firstChildNode-&gt;getAttributeNode("discid);

    //echo the value out to the browser
    echo ("The value of the discid attribute is: \n&lt;br /&gt;" . 
      $attrNode-&gt;getValue());
  }
  else {
    echo ("I DO NOT have a discid attribute");
  }
}</programlisting></para>

        <para>The above example returns:<programlisting>The value of the discid attribute is:
bb0c3c0c</programlisting></para>
      </section>

      <section>
        <title>The <function>attributes</function> Keyword and Named Node
        Maps</title>

        <para>An attribute list is defined by the DOM specification as a
        <emphasis>Named Node Map</emphasis>. This is a type of node collection
        that allows you to access its members either by name or by
        index.</para>

        <para>Although the attribute specific methods are in most cases
        sufficient, there may be times when you do not know in advance the
        names of an elements attributes. Using the named node map methods, you
        can query ther list to find out this data.</para>

        <section>
          <title>The <function>attributes</function> Keyword</title>

          <para>To obtain a reference to the attributes list /named node map
          of an element, use the <function>attributes</function>
          keyword:</para>

          <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //get a reference to the attributes list / named node map (don't forget the ampersand!)
  $attrList =&amp; $firstChildNode-&gt;attributes;
}</programlisting></para>
        </section>

        <section>
          <title>getLength, item, and getName</title>

          <para>The <function>getLength</function> method of a named node map
          returns an integer indicating how many members belong to the
          attribute list.</para>

          <para>The <function>item</function> method of a named node map
          allows you to access a member by its numerical index (which is
          0-based). In combination with the <function>getLength</function>
          method, you can set up a loop through the members of an attribute
          list.</para>

          <para>The <function>getName</function> method will tell you the name
          of the node.</para>

          <para><programlisting>if ($cdCollection-&gt;documentElement-&gt;hasChildNodes()) {

  //get reference to first cd node (the Robbie Fulks cd)
  $firstChildNode =&amp; $cdCollection-&gt;documentElement-&gt;firstChild;

  //get a reference to the attributes list / named node map (don't forget the ampersand!)
  $attrList =&amp; $firstChildNode-&gt;attributes;

  //determine the number of members in the attribute list
  $numAttributes = $attrList-&gt;getLength();

  //iterate through the list
  for ($i = 0; $i &lt; $numAttributes; $i++) {
    //get a reference to the attribute node at index i (don't forget the ampersand!)   
    $currAttr =&amp; $attrList-&gt;item(i);

    //echo out the name and value of the attribute
    echo "The attribute at index " . i . " is named: " . $currAttr-&gt;getName();
    echo "\n&lt;br /&gt; Its value is: " . $currAttr-&gt;getValue(); 
  }
}</programlisting></para>

          <para>The above example returns:</para>

          <para><programlisting>The attribute at index 1 is named: discid
Its value is: bb0c3c0c</programlisting></para>
        </section>
      </section>
    </section>

    <section>
      <title>Accessing the XML Prolog</title>

      <para>The <emphasis>XML Prolog</emphasis> is a term referring to the XML
      Declaration and the Document Type Declaration.</para>

      <section>
        <title><function>getXMLDeclaration</function></title>

        <para>The XML declaration can be acquired with the
        <function>getXMLDeclaration</function> method:</para>

        <para><programlisting>$myXMLDecl =&amp; $xmldoc-&gt;getXMLDeclaration();</programlisting></para>

        <para>A reference to a processing instruction node is returned.</para>
      </section>

      <section>
        <title>Accessing the Document Type Declaration</title>

        <para>The Document Type Declaration can be acquired with the
        <computeroutput>getDocType</computeroutput> method:<programlisting>$myDTD =&amp; $xmldoc-&gt;getDocType();</programlisting></para>

        <para>A reference to a processing instruction node is returned.</para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>Creating and Modifying a DOM Document</title>

    <para>The major strength of the Document Object Model is the ease with
    which the data in an XML document can be modified. The following chapter
    delineates how to use DOMIT! for creating, appending, inserting,
    replacing, removing, and altering XML data.</para>

    <section>
      <title>Creating Nodes</title>

      <para>Creating new XML nodes is accomplished using a set of
      DOMIT_Document factory methods. For the next subsections, we will assume
      that a new DOMIT_Document has already been created as follows:</para>

      <para><programlisting>//include DOMIT! codebase
require_once('xml_domit_include.php');

//instantiate a new DOMIT! document
$xmldoc =&amp; new DOMIT_Document(); </programlisting></para>

      <section>
        <title><function>createElement</function></title>

        <para>To create a new DOM element, use the
        <function>createElement</function> method.</para>

        <para>The <function>createElement</function> method takes a single
        parameter -- the name of the element.</para>

        <para><programlisting>$newElement =&amp; $xmldoc-&gt;createElement("cdlibrary");</programlisting><remark>Note:
        Don't forget to include the ampersand for backwards compatibility with
        PHP4!</remark></para>
      </section>

      <section>
        <title><function>createTextNode</function></title>

        <para>To create a new DOM text node, use the
        <function>createTextNode</function> method.</para>

        <para>The <function>createTextNode</function> method takes a single
        parameter -- the text of the node.</para>

        <para><programlisting>$myText = 'Here is some dummy text';

$newTextNode =&amp; $xmldoc-&gt;createTextNode($myText);</programlisting></para>
      </section>

      <section>
        <title><function>createCDATASection</function></title>

        <para>To create a new DOM CDATA Section, use the
        <function>createCDATASection</function> method.</para>

        <para>The <function>createCDATASection</function> method takes a
        single parameter -- the text of the CDATA Section.</para>

        <para><programlisting>$myText = 'Here are some illegal XML characters: &amp; &lt;';

$newCDATASection =&amp; $xmldoc-&gt;createCDATASection($myText);</programlisting></para>
      </section>

      <section>
        <title><function>createAttribute</function></title>

        <para>To create a new DOM attribute, use the
        <function>createAttribute</function> method.</para>

        <para>The <function>createAttribute</function> method takes two
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the name of the attribute</para>
          </listitem>

          <listitem>
            <para>the value of the attribute</para>
          </listitem>
        </itemizedlist>

        <para><programlisting>$newAttribute =&amp; $xmldoc-&gt;createAttribute("discid", "bb0c3c0c");</programlisting></para>
      </section>

      <section>
        <title><function>createComment</function></title>

        <para>To create a new DOM comment, use the
        <function>createComment</function> method.</para>

        <para>The <function>createComment</function> method takes a single
        parameter -- the text of the comment.</para>

        <para><programlisting>$myCommentText = 'This is a comment';

$newCommentNode =&amp; $xmldoc-&gt;createComment($myCommentText);</programlisting></para>
      </section>

      <section>
        <title><function>createProcessingInstruction</function></title>

        <para>To create a new DOM processing instruction, use the
        <function>createProcessingInstruction</function> method.</para>

        <para>The <function>createProcessingInstruction</function> method
        takes a two parameters -- the text of the target and the text of the
        data.</para>

        <para><programlisting>//create target and data
$myTarget = 'xml';
$myData = 'version="1.0"';

//create processing instruction
$newProcessingInstructionNode =&amp; $xmldoc-&gt;createProcessingInstruction($myTarget, $myData);</programlisting></para>
      </section>
    </section>

    <section>
      <title>Appending Nodes</title>

      <para>Appending a node in the DOM means adding a new child node to the
      end of a node's child nodes list.</para>

      <para>You can use the <function>appendChild</function> method to append
      a node (and its children, if any exist) to a DOM Document or an element
      node.</para>

      <para>The following example creates a
      <computeroutput>&lt;cdlibrary&gt;</computeroutput> element and appends
      it to a new DOMIT_Document:</para>

      <para><programlisting>//include DOMIT! codebase
require_once('xml_domit_include.php');

//instantiate a new DOMIT! document
$xmldoc =&amp; new DOMIT_Document(); 

//create cdlibrary node
$newNode =&amp; $xmldoc-&gt;createElement('cdlibrary');

//append cdlibrary node to new DOMIT_Document
$xmldoc-&gt;appendChild($newNode);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;cdlibrary&gt;&lt;/cdlibrary&gt;</programlisting></para>
    </section>

    <section>
      <title>Setting the Document Element</title>

      <para>In the previous section, when the &lt;cdlibrary&gt; element was
      appended to the empty DOM document, it became the document
      element.</para>

      <para>The <function>setDocumentElement</function> method is another way
      of achieving the same result. For example:</para>

      <para><programlisting>//include DOMIT! codebase
require_once('xml_domit_include.php');

//instantiate a new DOMIT! document
$xmldoc =&amp; new DOMIT_Document(); 

//create cdlibrary node
$newNode =&amp; $xmldoc-&gt;createElement('cdlibrary');

//append cdlibrary node to new DOMIT_Document
$xmldoc-&gt;setDocumentElement($newNode);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;cdlibrary&gt;&lt;/cdlibrary&gt;</programlisting></para>

      <para><function>setDocumentElement</function> will overwrite an existing
      document element.</para>
    </section>

    <section>
      <title>Setting Attributes</title>

      <para>The <function>setAttribute</function> and
      <function>setAttributeNode</function> methods are used to either add an
      attribute to an element, or change the value of an existing attribute.
      They are methods of element nodes only.</para>

      <section>
        <title><function>setAttribute</function></title>

        <para>The <function>setAttribute</function> method takes two
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the name of the attribute to be added</para>
          </listitem>

          <listitem>
            <para>the value of the attribute to be appended</para>
          </listitem>
        </itemizedlist>

        <para>The following example adds a
        <computeroutput>discid</computeroutput> attribute to a
        <computeroutput>&lt;cd&gt;</computeroutput> element:</para>

        <para><programlisting>//create cd element
$newNode =&amp; $xmldoc-&gt;createElement('cd');

//add a discid attribute
$newNode-&gt;setAttribute('discid', 'bb0c3c0c');

//echo to browser
echo $newNode-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;cd discid="bb0c3c0c"&gt;&lt;/cd&gt;</programlisting></para>
      </section>

      <section>
        <title><function>setAttributeNode</function></title>

        <para>The <function>setAttribute</function> method also adds an
        attribute to an element. It takes a single parameter -- an attribute
        node:</para>

        <para><programlisting>//create cd element
$newNode =&amp; $xmldoc-&gt;createElement('cd');

//create a discid attribute node
$newAttr =&amp; $xmldoc-&gt;createAttribute('discid', 'bb0c3c0c');

//add the attribute node to the element
$newNode-&gt;setAttributeNode($newAttr);

//echo to browser
echo $newNode-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;cd discid="bb0c3c0c"&gt;&lt;/cd&gt;</programlisting></para>
      </section>
    </section>

    <section>
      <title>Creating the cdlibrary XML Using DOMIT!</title>

      <para>We now have sufficient tools to create the cdlibrary example from
      scratch, using only DOMIT!</para>

      <para><programlisting>//include DOMIT! codebase
require_once('xml_domit_include.php');

//instantiate a new DOMIT! document
$xmldoc =&amp; new DOMIT_Document(); 

//create XML declaration
$xmlDecl =&amp; $xmldoc-&gt;createProcessingInstruction('xml', 'version="1.0"');

//append XML declaration to new DOMIT_Document
$xmldoc-&gt;appendChild($xmlDecl);

//create cdlibrary node
$rootElement =&amp; $xmldoc-&gt;createElement('cdlibrary');

//append cdlibrary node to new DOMIT_Document
$xmldoc-&gt;appendChild($rootElement);

//CREATE FIRST CD ELEMENT AND CHILDREN
//create cd element
$cdElement_1 =&amp; $xmldoc-&gt;createElement('cd');

//add discid attribute
$cdElement_1-&gt;setAttribute('discid', 'bb0c3c0c');

//create name element
$nameElement =&amp; $xmldoc-&gt;createElement('name');

//create and append text node to name element
$nameElement-&gt;appendChild($xmldoc-&gt;createTextNode('Robbie Fulks'));

//append name element to cd element
$cdElement_1-&gt;appendChild($nameElement);

//create title element
$titleElement =&amp; $xmldoc-&gt;createElement('title');

//create and append text node to title element
$titleElement-&gt;appendChild($xmldoc-&gt;createTextNode('Couples in Trouble'));

//append title element to cd element
$cdElement_1-&gt;appendChild($titleElement);


//CREATE SECOND CD ELEMENT AND CHILDREN
//create cd element
$cdElement_2 =&amp; $xmldoc-&gt;createElement('cd');

//add discid attribute
$cdElement_2-&gt;setAttribute('discid', '9b0ce70c');

//create name element
$nameElement =&amp; $xmldoc-&gt;createElement('name');

//create and append text node to name element
$nameElement-&gt;appendChild($xmldoc-&gt;createTextNode('Richard Thompson'));

//append name element to cd element
$cdElement_2-&gt;appendChild($nameElement);

//create title element
$titleElement =&amp; $xmldoc-&gt;createElement('title');

//create and append text node to title element
$titleElement-&gt;appendChild($xmldoc-&gt;createTextNode('Mock Tudor'));

//append title element to cd element
$cdElement_2-&gt;appendChild($titleElement);


//CREATE THIRD CD ELEMENT AND CHILDREN
//create cd element
$cdElement_3 =&amp; $xmldoc-&gt;createElement('cd');

//add discid attribute
$cdElement_3-&gt;setAttribute('discid', 'cf11720f');

//create name element
$nameElement =&amp; $xmldoc-&gt;createElement('name');

//create and append text node to name element
$nameElement-&gt;appendChild($xmldoc-&gt;createTextNode('Keller Williams'));

//append name element to cd element
$cdElement_3-&gt;appendChild($nameElement);

//create title element
$titleElement =&amp; $xmldoc-&gt;createElement('title');

//create and append text node to title element
$titleElement-&gt;appendChild($xmldoc-&gt;createTextNode('Laugh'));

//append title element to cd element
$cdElement_3-&gt;appendChild($titleElement);

//APPEND CD ELEMENTS TO CDLIBARY ELEMENT
$rootElement-&gt;appendChild($cdElement_1);
$rootElement-&gt;appendChild($cdElement_2);
$rootElement-&gt;appendChild($cdElement_3);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
    </section>

    <section>
      <title>Inserting Nodes</title>

      <para>If you need to add a child node somewhere other than the end of
      the child nodes list, you can use the <function>insertBefore</function>
      method.</para>

      <para><function>insertBefore</function> takes two parameters:</para>

      <itemizedlist>
        <listitem>
          <para>a reference to the node that is to be added</para>
        </listitem>

        <listitem>
          <para>a reference to an existing child node, before which the
          insertion will occur</para>
        </listitem>
      </itemizedlist>

      <para>If, continuing with the cdlibrary document from the previous
      example, we wished to insert a comment as the first child node of the
      <computeroutput>&lt;cdlibrary&gt;</computeroutput> element,
      <function>insertBefore</function> could be used:</para>

      <para><programlisting>//create a comment
$myComment =&amp; $xmldoc-&gt;createComment('Not many cds left after I got robbed');

//insert the comment as the first child of the cdlibrary element
$rootElement-&gt;insertBefore($myComment, $rootElement-&gt;childNodes[0]);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;!--Not many cds left after I got robbed--&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
    </section>

    <section>
      <title>Replacing Nodes</title>

      <para>Let's say that I traded my Robbie Fulks cd for a Charlie Hunter cd
      named "Songs From the Analog Playground", and I want to replace the old
      XML with a new cd node.</para>

      <para>The <function>replaceChild</function> method can be used to do
      this. It takes two parameters:</para>

      <itemizedlist>
        <listitem>
          <para>a reference to the new node to be added</para>
        </listitem>

        <listitem>
          <para>a reference to the node that is to be replaced</para>
        </listitem>
      </itemizedlist>

      <para><programlisting>//CREATE NEW CHARLIE HUNTER CD ELEMENT AND CHILDREN
//create cd element
$cdElement_new =&amp; $xmldoc-&gt;createElement('cd');

//add discid attribute
$cdElement_new-&gt;setAttribute('discid', 'a30e4c0d');

//create name element
$nameElement =&amp; $xmldoc-&gt;createElement('name');

//create and append text node to name element
$nameElement-&gt;appendChild($xmldoc-&gt;createTextNode('Charlie Hunter'));

//append name element to cd element
$cdElement_new-&gt;appendChild($nameElement);

//create title element
$titleElement =&amp; $xmldoc-&gt;createElement('title');

//create and append text node to title element
$titleElement-&gt;appendChild($xmldoc-&gt;createTextNode('Songs From the Analog Playground'));

//append title element to cd element
$cdElement_new-&gt;appendChild($titleElement);

//REPLACE ROBIBIE FULKS CD NODE WITH CHARLIE HUNTER CD NODE
//(remember a comment has been added, so Robbie is the second child node)
$rootElement-&gt;replaceChild($cdElement_new, $rootElement-&gt;childNodes[1]);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;!--Not many cds left after I got robbed--&gt;
  &lt;cd discid="a30e4c0d"&gt;
    &lt;name&gt;Charlie Hunter&lt;/name&gt;
    &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
    </section>

    <section>
      <title>Removing Nodes</title>

      <para>The <function>removeChild</function> method allows you to delete a
      node (and its children) from a DOM document. It takes a single parameter
      -- a reference to the node to be removed.</para>

      <para>The following example removes the comment from the cdlibrary
      XML:</para>

      <para><programlisting>$rootElement-&gt;removeChild($rootElement-&gt;firstChild);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:<programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="a30e4c0d"&gt;
    &lt;name&gt;Charlie Hunter&lt;/name&gt;
    &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
    </section>

    <section>
      <title>Removing Attributes</title>

      <para>An attribute can be deleted with either the
      <function>removeAttribute</function> or
      <function>removeAttributeNode</function> method.</para>

      <section>
        <title><function>removeAttribute</function></title>

        <para>An attribute can be removed with the
        <function>removeAttribute</function> method. It takes a single
        parameter -- the name of the attribute to be removed.</para>

        <para>The following example removes the
        <computeroutput>discid</computeroutput> attribute from the Charlie
        Hunter <computeroutput>&lt;cd&gt;</computeroutput> element:</para>

        <para><programlisting>$rootElement-&gt;firstChild-&gt;removeAttribute('discid');

//echo to browser
echo $rootElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:<programlisting>&lt;cdlibrary&gt;
  &lt;cd&gt;
    &lt;name&gt;Charlie Hunter&lt;/name&gt;
    &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
      </section>

      <section>
        <title><function>removeAttributeNode</function></title>

        <para>An attribute can also be removed with the
        <function>removeAttributeNode</function> method. It takes a single
        parameter -- a reference to the attribute to be removed.</para>

        <para>The following example removes the
        <computeroutput>discid</computeroutput> attribute from the Charlie
        Hunter <computeroutput>&lt;cd&gt;</computeroutput> element:</para>

        <para><programlisting>//get reference to attribute to be removed
$attrToRemove =&amp; $rootElement-&gt;firstChild-&gt;getAttributeNode('discid');

//remove attribute
$rootElement-&gt;firstChild-&gt;removeAttributeNode($attrToRemove);

//echo to browser
echo $rootElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:<programlisting>&lt;cdlibrary&gt;
  &lt;cd&gt;
    &lt;name&gt;Charlie Hunter&lt;/name&gt;
    &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
      </section>
    </section>

    <section>
      <title>Setting Character Data</title>

      <para>There are a variety of methods available for working with
      character data nodes.</para>

      <section>
        <title><function>setText</function></title>

        <para>The <function>setText</function> method allows you to modify the
        text of an existing text node, CDATA Section, or comment.</para>

        <para>To change the title of the Keller Williams cd, for example, you
        would do this:</para>

        <para><programlisting>//get reference to title text node of Keller Williams cd 
$titleTextNode =&amp; $rootElement-&gt;childNodes[2]-&gt;childNodes[1]-&gt;firstChild;

//modify title
$titleTextNode-&gt;setText('Loop');

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="a30e4c0d"&gt;
    &lt;name&gt;Charlie Hunter&lt;/name&gt;
    &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Loop&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>

        <section>
          <title><function>setText</function> When Called from an
          Element</title>

          <para>If <function>setText</function> is called from an element
          instead of a text node, DOMIT! will check if the element has a child
          text node.</para>

          <para>If the element <emphasis>has</emphasis> a child text node, the
          text of that node will be set to the value specified in the
          <function>setText</function> parameter.</para>

          <para>If the element <emphasis>does not have</emphasis> a child text
          node, a new text node will be created, appended to the element, and
          its node value set to the value specified in the
          <function>setText</function> parameter. For instance:</para>

          <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//call setText on the element 
//(note that no child text node exists at this point, but one will be created)
$someElement-&gt;setText('Some sample text');

//echo to browser
echo $someElement-&gt;toNormalizedString(true);</programlisting></para>

          <para>The result is:</para>

          <para><programlisting>&lt;someElement&gt;Some sample text&lt;/someElement&gt;</programlisting></para>
        </section>
      </section>

      <section>
        <title><function>splitText</function></title>

        <para>The <function>splitText</function> method is accessible only
        from a text node. It allows you to split a text node into two text
        nodes, at a specified offset point. Both text nodes will be retained
        in the DOM tree as siblings.</para>

        <para><function>setText</function> takes a single integer parameter --
        the character index at which the node is to be split.</para>

        <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//add a text node to the element 
$someElement-&gt;setText('Some sample text');

//echo childCount to browser
echo '$someElement has ' . $someElement-&gt;childCount . ' child nodes.';

/add a text node to the element 
$someElement-&gt;firstChild-&gt;splitText(5);

//echo childCount to browser
echo "\n&lt;br /&gt;";
echo 'After calling splitText, $someElement now has ' . $someElement-&gt;childCount . ' child nodes.';</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>$someElement has 1 child nodes.
After calling splitText, $someElement now has 2 child nodes.</programlisting></para>
      </section>

      <section>
        <title><function>normalize</function></title>

        <para>The <function>normalize</function> method performs the opposite
        of the <function>splitText</function> method: it collapses adjacent
        text nodes into a single text node.</para>

        <para><function>normalize</function> can be called from any element or
        the DOM document itself, and is called recursively on all nodes below
        the calling node.</para>

        <para>The following example splits a text node using
        <function>splitNode</function>, then uses
        <function>normalize</function> to reverse the operation:</para>

        <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//add a text node to the element 
$someElement-&gt;setText('Some sample text');

//echo childCount to browser
echo '$someElement has ' . $someElement-&gt;childCount . ' child nodes.';

/add a text node to the element 
$someElement-&gt;firstChild-&gt;splitText(5);

//echo childCount to browser
echo "\n&lt;br /&gt;";
echo 'After calling splitText, $someElement now has ' . $someElement-&gt;childCount . ' child nodes.';

//call normalize on element to reverse splitText
$someElement-&gt;normalize();

//echo childCount to browser
echo "\n&lt;br /&gt;";
echo 'After calling normalize, $someElement now has ' . $someElement-&gt;childCount . ' child nodes.';</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>$someElement has 1 child nodes.
After calling splitText, $someElement now has 2 child nodes.
After calling normalize, $someElement now has 1 child nodes.</programlisting></para>
      </section>

      <section>
        <title><function>appendData</function></title>

        <para>The <function>appendData</function> method allows you to append
        text to a text node, CDATA Section, or comment node. For
        example:</para>

        <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//add a text node to the element 
$someElement-&gt;setText('Some sample text');

//append more text
$someElement-&gt;firstChild-&gt;appendData(' plus more text.');

//echo to browser
echo $someElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;someElement&gt;Some sample text plus more text.&lt;/someElement&gt;</programlisting></para>
      </section>

      <section>
        <title><function>insertData</function></title>

        <para>The <function>insertData</function> method allows you to insert
        text into a text node, CDATA Section, or comment node, as a specified
        offset.</para>

        <para>It takes two parameters: an integer indicating the insertion
        pont, and a string comprising the text to be inserted. For
        example:</para>

        <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//add a text node to the element 
$someElement-&gt;setText('Some sample text');

//insert some text
$someElement-&gt;firstChild-&gt;insertData(5, ' more');

//echo to browser
echo $someElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;someElement&gt;Some more sample text&lt;/someElement&gt;</programlisting></para>
      </section>

      <section>
        <title><function>replaceData</function></title>

        <para>The <function>replaceData</function> method allows you to
        overwrite a substring of text in a text node, CDATA Section, or
        comment node.</para>

        <para>It takes three parameters: an integer indicating the insertion
        pont, an integer specifying the number of characters from the
        insertion point to overwrite, and a string comprising the replacement
        text. For example:</para>

        <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//add a text node to the element 
$someElement-&gt;setText('Some sample text');

//replace some text
$someElement-&gt;firstChild-&gt;replaceData(0, 4, 'A bit of');

//echo to browser
echo $someElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;someElement&gt;A bit of sample text&lt;/someElement&gt;</programlisting></para>
      </section>

      <section>
        <title><function>deleteData</function></title>

        <para>The d<function>eleteData</function> method allows you to delete
        a substring of text in a text node, CDATA Section, or comment
        node.</para>

        <para>It takes two parameters: an integer indicating the insertion
        pont, and an integer specifying the number of characters from the
        insertion point to delete. For example:</para>

        <para><programlisting>//create a new element
$someElement =&amp; $xmldoc-&gt;createElement('someElement');

//add a text node to the element 
$someElement-&gt;setText('Some sample text');

//delete some text
$someElement-&gt;firstChild-&gt;deleteData(6, 7);

//echo to browser
echo $someElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;someElement&gt;Some text&lt;/someElement&gt;</programlisting></para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>Saving a DOM Document</title>

    <para>After modifying an XML document, you generally need to save it to
    the filesystem. This can be achieved using the
    <function>saveXML</function> method.</para>

    <para>saveXML takes two parameters:</para>

    <itemizedlist>
      <listitem>
        <para>the file path to save the document</para>
      </listitem>

      <listitem>
        <para>a boolean specifying whether
        <function>toNormalizedString</function> formatting should be applied
        to the saved XML</para>
      </listitem>
    </itemizedlist>

    <para>To save the cdlibrary XML you would do this:</para>

    <para><programlisting>$xmldoc-&gt;saveXML('/xml/cdcollection.xml', true)</programlisting></para>
  </chapter>

  <chapter>
    <title>Miscellaneous DOM Features</title>

    <para>The are a number of additional DOM methods and constructs that have
    not yet been covered in this tutorial. The following chapter illustrates
    these.</para>

    <section>
      <title><function>cloneNode</function></title>

      <para>The cloneNode method allows you to make an copy of a node and its
      children. All data in the cloned node will be identical to its source
      node, but the nodes are considered separate objects.</para>

      <para><function>cloneNode</function> takes a single parameter -- a
      boolean that if set to <emphasis role="bold">true</emphasis> will also
      clone all children of the node. The default value is <emphasis
      role="bold">true</emphasis>.</para>

      <para>Any type of node in a DOM document can be cloned.</para>

      <para>The following example clones the first
      <computeroutput>&lt;cd&gt;</computeroutput> element in the cdlibrary
      document and prints to the browser:</para>

      <para><programlisting>//get reference to first cd node
$firstCDNode =&amp; $cdCollection-&gt;documentElement-&gt;childNodes[1]; 

//echo to browser
echo $firstCDNode-&gt;toNormalizedString(true);

//clone first cd node
$clonedCDNode =&amp; $firstCDNode-&gt;cloneNode(true);

//echo to browser
echo "\n&lt;br /&gt;\n&lt;br /&gt;" . $clonedCDNode-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;

&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;</programlisting></para>
    </section>

    <section>
      <title><function>getElementByID</function></title>

      <para>The <function>getElementByID</function> method searches for
      elements with attributes of type ID, and returns an element with the
      specified value if one exists.</para>

      <para>The DOM specification explains that by default, the search does
      not match on elements with an attribute <emphasis>named</emphasis> "ID";
      rather, it is an <emphasis>attribute type </emphasis>that the method is
      looking for. The attribute type must either be:</para>

      <itemizedlist>
        <listitem>
          <para>defined in the document type declaration, i.e.,</para>

          <para><programlisting>&lt;!ATTLIST bar
    id ID #IMPLIED
  &gt;</programlisting></para>
        </listitem>

        <listitem>
          <para>an attribute named id must be prefixed with the namespace
          <emphasis>xml</emphasis></para>

          <para><programlisting>&lt;someElement xml:id="12345" /&gt;</programlisting></para>
        </listitem>
      </itemizedlist>

      <para>DOMIT! is a non-validating parser, so the first option is not
      available. DOMIT! does, however, recognize the second option. With the
      following xml document, for example...</para>

      <para><programlisting>&lt;testDocument&gt;
  &lt;someElement xml:id="12345"&gt;The containing element is properly formatted for getElementByID&lt;/someElement&gt;
  &lt;anotherElement id="12345"&gt;The containing element is NOT properly formatted for getElementByID&lt;/anotherElement&gt;
&lt;/testDocument&gt;</programlisting></para>

      <para>... the <function>getElementByID</function> method will match only
      on the first child node:</para>

      <para><programlisting>//instantiate and load XML
$xmldoc =&amp; new DOMIT_Document();
$success = $xmldoc-&gt;loadXML("testDocument.xml", true);

if ($success) {
  //search for element with an ID of "12345"
  $matchingNode =&amp; $xmldoc-&gt;getElementByID("12345");

  //echo matching node to browser if one exists
  if ($matchingNode != null) {
    echo $matchingNode-&gt;toNormalizedString(true);
  }
}</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;someElement xml:id="12345"&gt;The containing element is properly formatted for getElementByID&lt;/someElement&gt;</programlisting></para>

      <para>The <function>getElementByID</function> method returns <emphasis
      role="bold">null</emphasis> if no matching element is found.</para>

      <section>
        <title><function>getElementByID</function> and Strict vs. Tolerant
        mode</title>

        <para>Some may argue that the DOM specification for
        <function>getElementByID</function> is too rigid for practical
        purposes. When parsing XHTML in particular, it is common to match on
        ID attributes that are not defined in such a way that DOMIT! or other
        non-validating parsers can effectively match on elements.</para>

        <para>Given this, DOMIT! allows you to specify a
        <emphasis>tolerant</emphasis> mode for
        <function>getElementByID</function> searches. By passing in a second
        parameter of <emphasis role="bold">false</emphasis>, DOMIT! will match
        on elements with attributes of "ID" and "id".</para>

        <para>Take the following document, for example:</para>

        <para><programlisting>&lt;testDocument&gt;
  &lt;anotherElement id="12345"&gt;The containing element is NOT properly formatted for getElementByID&lt;/anotherElement&gt;
&lt;/testDocument&gt;</programlisting>If <function>getElementByID</function>
        is called:<programlisting>//instantiate and load XML
$xmldoc =&amp; new DOMIT_Document();
$success = $xmldoc-&gt;loadXML("testDocument.xml", true);

if ($success) {
  //search for element with an ID of "12345"
  $matchingNode =&amp; $xmldoc-&gt;getElementByID("12345");

  //echo matching node to browser if one exists
  if ($matchingNode != null) {
    echo $matchingNode-&gt;toNormalizedString(true);
  }
}</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;anotherElement xml:id="12345"&gt;The containing element is NOT properly formatted for getElementByID&lt;/anotherElement&gt;</programlisting></para>
      </section>
    </section>

    <section>
      <title><function>getElementsByTagName</function></title>

      <para>The <function>getElementsByTagName</function> method is similar to
      <function>getElementByID</function>, in that it is a method for
      searching a DOM document for elements which match certain
      criteria.</para>

      <para>In the case of <function>getElementByTagName</function>, the
      <emphasis>name</emphasis> of the element is matched on, and there can
      consequently be multiple matching elements.</para>

      <para><function>getElementsByTagName</function> takes a single parameter
      -- the tag name of the elements to match. The search is performed
      recursively through the entire subtree of the calling element.</para>

      <para>If one searched the cdlibrary XML for elements named "cd", for
      example, three elements would be returned:</para>

      <para><programlisting>$cdCollection =&amp; new DOMIT_Document();
$success = $cdCollection-&gt;loadXML("/xml/cdcollection.xml");

if ($success) {
  //use getElementsByTagName to gather all elements named "cd"
  $matchingNodes =&amp; $cdCollection-&gt;getElementsByTagName("cd");

  //if any matching nodes are found, echo to browser
  if ($matchingNodes != null) {
    echo $matchingNodes-&gt;toNormalizedString(true);
  }
}</programlisting></para>

      <para>The result is a printout of the three matched cd elements:</para>

      <para><programlisting>&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;
&lt;cd discid="9b0ce70c"&gt;
  &lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;/cd&gt;
&lt;cd discid="cf11720f"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  &lt;title&gt;Laugh&lt;/title&gt;
&lt;/cd&gt;</programlisting></para>
    </section>

    <section>
      <title>Using NodeLists</title>

      <para>In the previous section, the
      <function>getElementsByTagName</function> returned a collection of
      matching nodes. This collection is described by the DOM specification as
      a <emphasis>Node List</emphasis>.</para>

      <para>A node list is a collection of nodes accessible by numerical
      index. A number of methods are defined to access its members. Many of
      these are identical to those found in the previously discessed
      <emphasis>named node map</emphasis>.</para>

      <section>
        <title><function>getLength</function> and
        <function>item</function></title>

        <para>The <function>getLength</function> and item
        <function>methods</function> for a node list are identical to those
        for a named node map. You can use them to iterate through the node
        list using a for loop.</para>

        <para>Take the previous <function>getElementsByTagName</function>
        example, which returned three nodes. You can, for instance, loop
        through the node list and print out the
        <computeroutput>discid</computeroutput> of each CD:</para>

        <para><programlisting>//use getElementsByTagName to gather all elements named "cd"
$matchingNodes =&amp; $cdCollection-&gt;getElementsByTagName("cd");

//if any matching nodes are found, loop through them and print out disc id
if ($matchingNodes != null) {
  
  //get total number of nodes in the list
  $total = $matchingNodes-&gt;getLength();

  //loop through node list 
  for ($i = 0; $i &lt; $total; $i++) {

    //get current node on list
    $currNode =&amp; $matchingNodes-&gt;item($i);

    //echo out discid
    echo $currNode-&gt;getAttribute('discid') . "\n&lt;br /&gt;";
  }
}</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>bb0c3c0c
9b0ce70c
cf11720f</programlisting></para>
      </section>

      <section>
        <title><function>appendNode</function> and
        <function>removeNode</function></title>

        <para>The <function>appendNode</function> method allows you to add a
        node to the end of the node list. The <function>removeNode</function>
        method allows you to remove a node from the node list.</para>

        <para>Both methods take a single parameter -- a reference to the node
        being appended or removed.</para>

        <para>To <emphasis>append a node</emphasis> to the cd node list from
        the above example, you could do this:</para>

        <para><programlisting>//use getElementsByTagName to gather all elements named "cd"
$matchingNodes =&amp; $cdCollection-&gt;getElementsByTagName("cd");

//create a new node
$newNode =&amp; $cdCollection-&gt;createElement("someElement");

//append the node to the node list
$matchingNodes-&gt;appendNode($newNode);

//echo to browser
echo $matchingNodes-&gt;toNormalizedString(true);</programlisting>The result
        is:</para>

        <para><programlisting>&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;
&lt;cd discid="9b0ce70c"&gt;
  &lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;/cd&gt;
&lt;cd discid="cf11720f"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  &lt;title&gt;Laugh&lt;/title&gt;
&lt;/cd&gt;
&lt;someElement /&gt;</programlisting></para>

        <para>To r<emphasis>emove a node</emphasis> from the cd node list from
        the above example, you could do this:</para>

        <para><programlisting>//use getElementsByTagName to gather all elements named "cd"
$matchingNodes =&amp; $cdCollection-&gt;getElementsByTagName("cd");

//remove the first node from the node list
$matchingNodes-&gt;removeNode($matchingNodes-&gt;item(0));

//echo to browser
echo $matchingNodes-&gt;toNormalizedString(true);</programlisting>The result
        is:</para>

        <para><programlisting>&lt;cd discid="9b0ce70c"&gt;
  &lt;name&gt;Richard Thompson&lt;/name&gt;
  &lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;/cd&gt;
&lt;cd discid="cf11720f"&gt;
  &lt;name&gt;Keller Williams&lt;/name&gt;
  &lt;title&gt;Laugh&lt;/title&gt;
&lt;/cd&gt;</programlisting></para>
      </section>

      <section>
        <title>childNodesAsNodeList</title>

        <para>According to the DOM specification, the child nodes of an
        element should be kept in a node list.</para>

        <para>However, contrary to the specification, DOMIT! uses an array
        rather than a node list. This is to get around a deficiency in PHP 4,
        in which method calls cannot be chained together as one would normally
        expect with an object oriented programming language.</para>

        <para>You cannot, for instance, do this in PHP4 (although you can in
        PHP5)...</para>

        <para><programlisting>$myText = $xmldoc-&gt;documentElement-&gt;getChildNodes()-&gt;item(2)-&gt;getText();</programlisting></para>

        <para>...although by using an array, it is possible to burrow deeply
        down into a document structure without splitting your code into
        multiple lines:</para>

        <para><programlisting>$myText = $xmldoc-&gt;documentElement-&gt;childNodes[2]-&gt;getText();</programlisting></para>

        <para>For those who are using PHP5 and would like child nodes to be
        returned in node list format, the
        <function>childNodesAsNodeList</function> method can be used:</para>

        <para><programlisting>$myText = $documentElement-&gt;childNodesAsNodeList()-&gt;item(2)-&gt;getText();</programlisting></para>
      </section>
    </section>

    <section>
      <title><function>importNode</function></title>

      <para>The <function>importNode</function> method allows you to properly
      import a node into a DOM document which originated from another DOM
      document.</para>

      <para>It takes two parameters:</para>

      <itemizedlist>
        <listitem>
          <para>the node to be imported</para>
        </listitem>

        <listitem>
          <para>a boolean that, if <emphasis role="bold">true</emphasis>, will
          also import all the nodes children (this is default behavior)</para>
        </listitem>
      </itemizedlist>

      <para>Let's say we had two XML document. The first is the cd collection
      that we have been using throughout this tutorial. The second document
      contains a single cd that looks like this:</para>

      <para><programlisting>&lt;cd discid="a30e4c0d"&gt;
  &lt;name&gt;Charlie Hunter&lt;/name&gt;
  &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
&lt;/cd&gt;</programlisting></para>

      <para>If we instantiated these two XML documents, and wanted to add the
      contents of the <computeroutput>cd</computeroutput> document to the
      <computeroutput>cdlibrary</computeroutput> , we would first have to use
      <function>importNode</function>:</para>

      <para><programlisting>//instantiate and load first XML Document
$xmldoc1 =&amp; new DOMIT_Document();
$success1 = $xmldoc-&gt;loadXML("cdCollection.xml", true);

//instantiate and load second XML Document
$xmldoc2 =&amp; new DOMIT_Document();
$success2 = $xmldoc-&gt;loadXML("cd.xml", true);

//import contents of xmldoc2 into xmldoc1
$importedData =&amp; $xmldoc1-&gt;importNode($xmldoc2-&gt;documentElement);

//append contents of xmldoc2 to the cdCollection node
$xmldoc1-&gt;documentElement-&gt;appendChild($importedData);

//echo to browser
echo $xmldoc1-&gt;toNormalizedString(true);</programlisting></para>

      <para>The result is:</para>

      <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="a30e4c0d"&gt;
    &lt;name&gt;Charlie Hunter&lt;/name&gt;
    &lt;title&gt;Songs From the Analog Playground&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>
    </section>
  </chapter>

  <chapter>
    <title>Custom DOMIT! Methods</title>

    <para>DOMIT! includes a number of non-DOM methods for XML
    processing.</para>

    <section>
      <title><function>getVersion</function></title>

      <para>The <function>getVersion</function> method returns the version
      number of the current install of DOMIT!</para>

      <para><programlisting>$myVersion = $xmldoc-&gt;getVersion();</programlisting></para>
    </section>

    <section>
      <title>Searching for Nodes</title>

      <para>Although the <function>getElementByID</function> and
      <function>getElementsByTagName</function> methods are useful, often you
      need more sophisticated search options to simplify you XML code.</para>

      <section>
        <title><function>getElementsByPath</function></title>

        <para>The <function>getElementsByPath</function> method allows you to
        search for elements in a document that match a "path"-like pattern
        that you provide.</para>

        <para>The syntax is similar to an <ulink
        url="http://www.w3.org/TR/xpath">XPath</ulink> query, although the
        range of patterns allowed by <function>getElementsByPath</function> is
        far less sophisticated than the XPath specification permits.</para>

        <para>The pattern takes the basic form of
        <emphasis>elementName/elementName</emphasis>, where the forward slash
        represents a parent-child relationship. Either a node list, a single
        node, or null is returned</para>

        <para><function>getElementsByPath</function> can be called by any
        node. There are three basic ways that you can form a pattern:</para>

        <itemizedlist>
          <listitem>
            <para>An <emphasis role="bold">absolute path search</emphasis> can
            be performed by prefixing your pattern with the <emphasis
            role="bold">/</emphasis> character. This type of search will start
            at the level of the document element node.</para>
          </listitem>

          <listitem>
            <para>A <emphasis role="bold">relative path search</emphasis> can
            be performed by <emphasis>omitting</emphasis> the <emphasis
            role="bold">/</emphasis> prefix from your pattern. This type of
            search will start at the level of the node which called
            getElementsByPath.</para>
          </listitem>

          <listitem>
            <para>A <emphasis role="bold">variable path search</emphasis> can
            be performed by prefixing your pattern with <emphasis
            role="bold">//</emphasis> characters. This type of search will
            find all matching elements, regardless of their position in the
            node hierarchy.</para>
          </listitem>
        </itemizedlist>

        <para>Let's try an example of each with our cdlibrary XML:</para>

        <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting></para>

        <section>
          <title>Absolute Path Search</title>

          <para>The pattern for an absolute path search begins with a forward
          slash, meaning that the search will begin at the level of the
          document element node -- no matter what level the calling node
          resides.</para>

          <para>To perform an absolute search for all
          <computeroutput>&lt;title&gt;</computeroutput> elements, one would
          do this:</para>

          <para><programlisting>//use getElementsByPath to retrieve all title elements
$myNodeList =&amp; $cdCollection-&gt;getElementsByPath("/cdlibrary/cd/title");

//echo to browser
echo $myNodeList-&gt;toNormalizedString(true);</programlisting></para>

          <para>The result is a listing of the three found
          <computeroutput>&lt;title&gt;</computeroutput> nodes:</para>

          <para><programlisting>&lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;title&gt;Laugh&lt;/title&gt;</programlisting></para>
        </section>

        <section>
          <title>Relative Path Search</title>

          <para>The pattern for a relative path search does not contain a
          beginning forward slash. The search will begin at the level of the
          calling node.</para>

          <para>To perform an relative search for all
          <computeroutput>&lt;name&gt;</computeroutput> elements which are
          children of <computeroutput>&lt;cd&gt;</computeroutput> elements
          which are children of the
          <computeroutput>&lt;cdlibrary&gt;</computeroutput> element, one
          would do this:</para>

          <para><programlisting>//use getElementsByPath to retrieve all name elements which are children of 
//cd elements which are children of the cdlibrary element
$myNodeList =&amp; $cdCollection-&gt;documentElement-&gt;getElementsByPath("cd/name");

//echo to browser
echo $myNodeList-&gt;toNormalizedString(true);</programlisting></para>

          <para>The result is a listing of the three found
          <computeroutput>&lt;name&gt;</computeroutput> nodes:</para>

          <para><programlisting>&lt;name&gt;Robbie Fulks&lt;/name&gt;
&lt;name&gt;Richard Thompson&lt;/name&gt;
&lt;name&gt;Keller Williams&lt;/name&gt;</programlisting></para>
        </section>

        <section>
          <title>Variable Path Search</title>

          <para>The pattern for a variable path search begins with a double
          forward slash. Each element in the document is be considered a
          starting point for the search.</para>

          <para>To perform a variable search for all
          <computeroutput>&lt;title&gt;</computeroutput> elements in the
          document, one would do this:</para>

          <para><programlisting>//use getElementsByPath to retrieve all title elements in cdlibrary
$myNodeList =&amp; $cdCollection-&gt;getElementsByPath("//title");

//echo to browser
echo $myNodeList-&gt;toNormalizedString(true);</programlisting></para>

          <para>The result is a listing of the three found
          <computeroutput>&lt;title&gt;</computeroutput> nodes:</para>

          <para><programlisting>&lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;title&gt;Mock Tudor&lt;/title&gt;
&lt;title&gt;Laugh&lt;/title&gt;</programlisting></para>
        </section>

        <section>
          <title>Returning a Single Node Instead of a Node List</title>

          <para>If you would like a single node to be returned by
          <function>getElementsByPath</function>, rather than the entire node
          list of matching elements, you can specify the index of the
          requested node by passing an integer as the second parameter of
          <function>getElementsByPath</function>.</para>

          <para>In accordance with the XPath specification, the index that you
          specify is 1-based.</para>

          <para>To return the first
          <computeroutput>&lt;cd&gt;</computeroutput> node of the cdlibrary
          example, you could do this:<programlisting>//use getElementsByPath to retrieve the first cd element in cdlibrary
$myElement =&amp; $cdCollection-&gt;getElementsByPath("/cdlibrary/cd", 1);

//echo to browser
if ($myElement != null) {
  echo $myElement-&gt;toNormalizedString(true);
}</programlisting></para>

          <para>The result is:</para>

          <para><programlisting>&lt;cd discid="bb0c3c0c"&gt;
  &lt;name&gt;Robbie Fulks&lt;/name&gt;
  &lt;title&gt;Couples in Trouble&lt;/title&gt;
&lt;/cd&gt;</programlisting></para>
        </section>
      </section>

      <section>
        <title><function>getElementsByAttribute</function></title>

        <para>The <function>getElementsByAttribute</function> method allows
        you to retrieve a node list of elements, each of which contain an
        attribute that matches the specified name and value. This is a useful
        improvement over the <function>getElementByID</function> method, since
        it does not require you to be bound to a narrow definition of
        attribute type or name.</para>

        <para>To obtain a node list of all elements containing an attribute
        named 'myAttr' and a value of '3', for example, you would do
        this:</para>

        <para><programlisting>//get node list of elements containing myAttr="3"
$myNodeList =&amp; $xmldoc-&gt;getElementsByAttribute('myAttr', '3');</programlisting></para>

        <para>There is a third parameter available for
        <function>getElementsByAttribute</function>, a boolean which if set to
        <emphasis role="bold">true</emphasis> will return the<emphasis> first
        matching element</emphasis> rather than an entire node list of
        elements:</para>

        <para><programlisting>//get first matching elements containing myAttr="3"
$myElement =&amp; $xmldoc-&gt;getElementsByAttribute('myAttr', '3', true);</programlisting></para>
      </section>

      <section>
        <title><function>getNodesByNodeType</function></title>

        <para>The <function>getNodesByNodeType</function> method allows you to
        search the document tree for nodes of a specific <emphasis>node
        type</emphasis>.</para>

        <para>You can specify a node type using one of the following DOMIT!
        constants:</para>

        <itemizedlist>
          <listitem>
            <para><function>DOMIT_ELEMENT_NODE</function> (an integer value of
            1)</para>
          </listitem>

          <listitem>
            <para><function>DOMIT_TEXT_NODE</function> (an integer value of
            3)</para>
          </listitem>

          <listitem>
            <para><function>DOMIT_CDATA_SECTION_NODE</function> (an integer
            value of 4)</para>
          </listitem>

          <listitem>
            <para><function>DOMIT_PROCESSING_INSTRUCTION_NODE</function> (an
            integer value of 7)</para>
          </listitem>

          <listitem>
            <para><function>DOMIT_COMMENT_NODE</function> (an integer value of
            8)</para>
          </listitem>

          <listitem>
            <para><function>DOMIT_DOCUMENT_NODE</function> (an integer value
            of 9)</para>
          </listitem>
        </itemizedlist>

        <para>You must also pass in as the second parameter a context node - a
        node from which the search should start.</para>

        <para>The following example returns a node list of all text nodes in
        the cdlibrary example:</para>

        <para><programlisting>//find all text nodes in cdlibrary
$myTextNodeList =&amp; $cdCollection-&gt;getNodesByNodeType(DOMIT_TEXT_NODE, $cdCollection);

//echo to browser
echo $myTextNodeList-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>Robbie Fulks
Couples in Trouble
Richard Thompson
Mock Tudor
Keller Williams
Laugh</programlisting></para>
      </section>

      <section>
        <title><function>getNodesByNodeValue</function></title>

        <para>The <function>getNodesByNodeValue</function> method allows you
        to search the document tree for nodes of a specific <emphasis>node
        value</emphasis>.</para>

        <para>This is especially useful for finding text or CDATA Section
        nodes containing a certain text value.</para>

        <para>You must pass in the node value that you are searching for as
        well as a context node - a node from which the search should
        start.</para>

        <para>The following example returns a node list of all nodes in the
        current document with a node value of "Robbie Fulks":</para>

        <para><programlisting>//find all text nodes with a value of "Robbie Fulks" in cdlibrary
$myTextNodeList =&amp; $cdCollection-&gt;getNodesByNodeValue("Robbie Fulks", $cdCollection);

//get first match
$firstItem =&amp; $myTextNodeList-&gt;item(0);

//echo parent node to browser
echo $firstItem-&gt;parentNode-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;name&gt;Robbie Fulks&lt;/name&gt;</programlisting></para>
      </section>
    </section>

    <section>
      <title>XML to and from Arrays</title>

      <para>Sometimes it is useful to convert an XML document into a PHP
      array, or to import a PHP array as an XML document.</para>

      <para>DOMIT! provides two methods to accomplish this:
      <function>toArray</function>, and
      <function>DOMIT_Utilities::fromArray</function>.</para>

      <para><remark>Note: It may be faster to use the PHP/Expat method <ulink
      url="http://www.php.net/manual/en/function.xml-parse-into-struct.php">xml_parse_into_struct</ulink>
      instead of the DOMIT! array methods when converting XML to
      arrays.</remark></para>

      <section>
        <title><function>toArray</function></title>

        <para>The <function>toArray</function> method converts an xml node and
        its children to an array.</para>

        <para>To convert the first <computeroutput>&lt;cd&gt;</computeroutput>
        element of the cdlibrary example to an array, you would do
        this:</para>

        <para><programlisting>//convert first &lt;cd&gt; element to array
$myArray =&amp; $cdCollection-&gt;documentElement-&gt;firstChild-&gt;toArray();

//echo to browser
print "&lt;pre&gt;";
print_r($myArray);
print "&lt;/pre&gt;";</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>Array
(
    [cd] =&gt; Array
        (
            [attributes] =&gt; Array
                (
                    [discid] =&gt; bb0c3c0c
                )

            [0] =&gt; Array
                (
                    [name] =&gt; Array
                        (
                            [attributes] =&gt; Array
                                (
                                )

                            [0] =&gt; Robbie Fulks
                        )

                )

            [1] =&gt; Array
                (
                    [title] =&gt; Array
                        (
                            [attributes] =&gt; Array
                                (
                                )

                            [0] =&gt; Couples in Trouble
                        )

                )

        )

)</programlisting></para>
      </section>

      <section>
        <title><function>DOMIT_Utilities::fromArray</function></title>

        <para>The <function>DOMIT_Utilities::fromArray</function> method
        generates a node tree from an array and appends it to the specified
        document or node.</para>

        <para>The convention follows that of the fromArray method in the
        minixml library:</para>

        <para><programlisting>//Create an array to represent a person Bob
$bob = array(
  'name' =&gt; array( 
    'first' =&gt; 'Bob',
    'last' =&gt; 'Roberts'
  ),
  'age' =&gt; 35,
  'email' =&gt; 'bob@example.com',
  'location' =&gt; array(
    'streetaddr' =&gt; '123 Skid Row',
    'city' =&gt; 'Dark City',
    'state' =&gt; 'DN',
    'country' =&gt; 'XNE',
  ),
);


//Create another array to represent a person Mary
$mary = array(
  'name' =&gt; array( 
    'first' =&gt; 'Mary',
    'last' =&gt; 'Zlipsakis'
  ),
  'age' =&gt; 94,
  'location' =&gt; array(
    'streetaddr'=&gt; '54343 Park Ave',
    'city' =&gt; 'SmallVille',
    'state' =&gt; 'DN',
    'country' =&gt; 'XNE',
  ),
  'icecream' =&gt; 'vanilla',
);


//Create a big array that contains all our people
$xmlArray = array();
$xmlArray["people"]["person"] = array();

array_push($xmlArray["people"]["person"], $mary);
array_push($xmlArray["people"]["person"], $bob);

//instatiate a DOMIT! document
require_once('xml_domit_include.php');
$xmldoc =&amp; new DOMIT_Document();

//require DOMIT_Utilities file
require_once('xml_domit_utilities.php');

//use fromArray to populate document
DOMIT_Utilities::fromArray($xmldoc, $xmlArray);

//echo to browser
echo $xmldoc-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;people&gt;
    &lt;person&gt;
        &lt;name&gt;
            &lt;first&gt;Mary&lt;/first&gt;
            &lt;last&gt;Zlipsakis&lt;/last&gt;
        &lt;/name&gt;
        &lt;age&gt;94&lt;/age&gt;
        &lt;location&gt;
            &lt;streetaddr&gt;54343 Park Ave&lt;/streetaddr&gt;
            &lt;city&gt;SmallVille&lt;/city&gt;
            &lt;state&gt;DN&lt;/state&gt;
            &lt;country&gt;XNE&lt;/country&gt;
        &lt;/location&gt;
        &lt;icecream&gt;vanilla&lt;/icecream&gt;
    &lt;/person&gt;
    &lt;person&gt;
        &lt;name&gt;
            &lt;first&gt;Bob&lt;/first&gt;
            &lt;last&gt;Roberts&lt;/last&gt;
        &lt;/name&gt;
        &lt;age&gt;35&lt;/age&gt;
        &lt;email&gt;bob@example.com&lt;/email&gt;
        &lt;location&gt;
            &lt;streetaddr&gt;123 Skid Row&lt;/streetaddr&gt;
            &lt;city&gt;Dark City&lt;/city&gt;
            &lt;state&gt;DN&lt;/state&gt;
            &lt;country&gt;XNE&lt;/country&gt;
        &lt;/location&gt;
    &lt;/person&gt;
&lt;/people&gt;</programlisting></para>
      </section>
    </section>

    <section>
      <title>The nodetools Library</title>

      <para>The <function>nodetools</function> library is a set of helper
      utilities for processing nodes.</para>

      <section>
        <title><function>nodetools::parseAttributes</function></title>

        <para>The <function>nodetools::parseattributes</function> method
        parses an attribute string into an array of key / value pairs.</para>

        <para>For example:</para>

        <para><programlisting>//require the nodetools library
require_once('xml_domit_nodetools.php');

//build a sample attribute string
$myAttrString = 'x="27" y="12"';

//parse into an array
$myArray = nodetools::parseattributes($myAttrString);

//echo to browser
echo "&lt;pre&gt;";
print_r($myArray);
echo "&lt;/pre&gt;";</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>Array
(
    [x] =&gt; 27
    [y] =&gt; 12
)</programlisting></para>
      </section>

      <section>
        <title><function>nodetools::moveUp</function></title>

        <para>The <function>nodetools::moveUp</function> method moves a node
        to the <emphasis>previous</emphasis> index in the
        <computeroutput>childNodes</computeroutput> array.</para>

        <para>It takes a single argument -- a reference to the node to be
        moved.</para>

        <para>The following example moves the last
        <computeroutput>&lt;cd&gt;</computeroutput> element to the second last
        position:</para>

        <para><programlisting>//require the nodetools library
require_once('xml_domit_nodetools.php');

//move the node up
nodetools::moveUp($cdCollection-&gt;documentElement-&gt;lastChild);

//echo to browser
$cdCollection-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>
      </section>

      <section>
        <title><function>nodetools::moveDown</function></title>

        <para>The <function>nodetools::moveDown</function> method moves a node
        to the <emphasis>next</emphasis> index in the
        <computeroutput>childNodes</computeroutput> array.</para>

        <para>It takes a single argument -- a reference to the node to be
        moved.</para>

        <para>The following example moves the first
        <computeroutput>&lt;cd&gt;</computeroutput> element to the second
        position:</para>

        <para><programlisting>//require the nodetools library
require_once('xml_domit_nodetools.php');

//move the node up
nodetools::moveDown($cdCollection-&gt;documentElement-&gt;firstChild);

//echo to browser
$cdCollection-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <programlisting>&lt;?xml version="1.0"?&gt;
&lt;cdlibrary&gt;
  &lt;cd discid="9b0ce70c"&gt;
    &lt;name&gt;Richard Thompson&lt;/name&gt;
    &lt;title&gt;Mock Tudor&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="bb0c3c0c"&gt;
    &lt;name&gt;Robbie Fulks&lt;/name&gt;
    &lt;title&gt;Couples in Trouble&lt;/title&gt;
  &lt;/cd&gt;
  &lt;cd discid="cf11720f"&gt;
    &lt;name&gt;Keller Williams&lt;/name&gt;
    &lt;title&gt;Laugh&lt;/title&gt;
  &lt;/cd&gt;
&lt;/cdlibrary&gt;</programlisting>
      </section>

      <section>
        <title><function>nodetools::nodeExists</function></title>

        <para>The <function>nodetools::nodeExists</function> method checks
        whether a node exists.on a given path. The path expression must
        conforming to the <function>getElementsByPath</function>
        syntax.</para>

        <para>The method takes two parameters -- a reference to the calling
        node (the node at which the search begins) and the path
        expression.</para>

        <para>To check if the first child
        <computeroutput>&lt;cd&gt;</computeroutput> element of the
        <computeroutput>&lt;cdlibrary&gt;</computeroutput> element contains a
        <computeroutput>&lt;title&gt;</computeroutput> element, you can do
        this:</para>

        <para><programlisting>//require the nodetools library
require_once('xml_domit_nodetools.php');

//check if node exists
if (nodetools::nodeExists($cdCollection, '/cdlibrary/cd/title') {
  echo "Node exists!";
}
else {
  echo "Node does NOT exist";
}</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>Node exists!</programlisting></para>
      </section>

      <section>
        <title><function>nodetools::fromPath</function></title>

        <para>The <function>nodetools::fromPath</function> method generates a
        heirarchy of elements based on a path expression.</para>

        <para>It takes three parameters:</para>

        <itemizedlist>
          <listitem>
            <para>a reference to the DOMIT_Document that will create the
            elements</para>
          </listitem>

          <listitem>
            <para>the path expression</para>
          </listitem>

          <listitem>
            <para>the node value of a text node to be appended to the last
            element (if required)</para>
          </listitem>
        </itemizedlist>

        <para>For example:</para>

        <para><programlisting>//require the nodetools library
require_once('xml_domit_nodetools.php');

//build node tree
$myNodes =&amp; nodetools::fromPath($xmldoc, '/someElement/childElement', "Sample text");

//echo to browser
echo $myNodes-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;someElement&gt;
  &lt;childElement&gt;Sample text&lt;/childElement&gt;
&lt;/someElement&gt;</programlisting></para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>XML Namespaces</title>

    <para>The following chapter deals with XML namespaces. The <ulink
    url="http://www.w3.org/TR/REC-xml-names/">XML Namespaces
    specification</ulink> defines a simple method for distinguishing XML and
    element and attribute names, by associating them with URI references
    (namespaces).</para>

    <section>
      <title>Introduction to XML Namespaces</title>

      <para>With the widespread adoption of XML, we have increasingly seen the
      coexistence and integration of different XML standards.</para>

      <para>So what happens when you want to combine two XML documents, and
      each document contains an element named
      <computeroutput>&lt;title&gt;</computeroutput>, but the
      <computeroutput>&lt;title&gt;</computeroutput> element has a different
      meaning in each document? For example:</para>

      <para><programlisting><emphasis role="bold">XML DOCUMENT #1:</emphasis>
&lt;?xml version="1.0"?&gt;
&lt;individual gender="m"&gt;
  &lt;name&gt;George Henry III&lt;/name&gt;
  &lt;title&gt;Duke of Fredericton&lt;/title&gt;
  &lt;books&gt;&lt;/books&gt;
&lt;/individual&gt;


<emphasis role="bold">XML DOCUMENT #2:</emphasis>
&lt;?xml version="1.0"?&gt;
&lt;book&gt;
  &lt;title&gt;Transcendence Through XML&lt;/title&gt;
&lt;/book&gt;


<emphasis role="bold">COMBINED DOCUMENT:</emphasis>
&lt;?xml version="1.0"?&gt;
&lt;individual gender="m"&gt;
  &lt;name&gt;George Henry III&lt;/name&gt;
  &lt;title&gt;Duke of Fredericton&lt;/title&gt;
  &lt;books&gt;
    &lt;book&gt;
      &lt;title&gt;Transcendence Through XML&lt;/title&gt;
    &lt;/book&gt;
  &lt;/books&gt;
&lt;/individual&gt;</programlisting></para>

      <para>The potential problems here should be obvious. If, for instance,
      the <function>getElementsByTagName</function> method was used to obtain
      a node list of elements with the a node name of "title", how would one
      differentiate between a person's title, and the title of a book?</para>

      <para>Such naming collisions can cause confusion and error, and it is
      essential to have some means of differentiating between identically
      named, but contextually different, nodes.</para>

      <section>
        <title>URIs, Namespace Prefixes, and Namespace Declarations</title>

        <para>The XML Namespace specification proposes a mechanism whereby
        elements and attributes can be assigned
        <emphasis>namespaces</emphasis> -- or, unique identifiers that allow
        one to differentiate between similar tag names.</para>

        <para>The unique identifier comes in the form of a URI (Uniform
        Resource Identifier), which is a convention for identifying resources
        on the web (an URL, or universal resource locator, is a type of
        URI).</para>

        <para>For example, the namespace URI for the <ulink
        url="http://dublincore.org/">Dublin Core</ulink> -- an XML
        specification for interoperable online metadata standards --
        is:</para>

        <para><programlisting>http://purl.org/dc/elements/1.1/</programlisting></para>

        <para>Since the URI tends to be somewhat longish to appear frequently
        in your document, you can specify an abbreviation for the URI, know as
        the <emphasis>Namespace Prefix</emphasis>.</para>

        <para>The namespace URI and namespace prefix are defined within your
        XML document, often at the level of the document element (but not
        necessarily so), using the keyword <emphasis
        role="bold">xmlns</emphasis>.</para>

        <para>In our <computeroutput>&lt;individual&gt;</computeroutput>
        example from above, we might use namespaces to do the
        following:</para>

        <para><programlisting>&lt;?xml version="1.0"?&gt;
&lt;person:individual person:gender="m"
        xmlns:person="http://www.engageinteractive.com/person/"
        xmlns:book="http://www.engageinteractive.com/book/"&gt;
  &lt;person:name&gt;George Henry III&lt;/person:name&gt;
  &lt;person:title&gt;Duke of Fredericton&lt;/person:title&gt;
  &lt;person:books&gt;
    &lt;book:book&gt;
      &lt;book:title&gt;Transcendence Through XML&lt;/book:title&gt;
    &lt;/book:book&gt;
  &lt;/person:books&gt;
&lt;/person:individual&gt;</programlisting></para>

        <para>You'll notice that in the document element node, two items have
        been added which appear to be attributes but which are actually
        <emphasis>Namespace Declarations</emphasis>. A namespace
        declaration:</para>

        <itemizedlist>
          <listitem>
            <para>begins with the prefix
            <computeroutput>xmlns:</computeroutput></para>
          </listitem>

          <listitem>
            <para>is followed by the namespace prefix: e.g.,
            <computeroutput>person</computeroutput></para>
          </listitem>

          <listitem>
            <para>is followed by an equal sign</para>
          </listitem>

          <listitem>
            <para>concludes with the URI in quotation marks: e.g.
            <computeroutput>"http://www.engageinteractive.com/person/"</computeroutput></para>
          </listitem>
        </itemizedlist>

        <para>The namespace declaration says basically that:</para>

        <para><emphasis>There are elements and /or attributes in the following
        XML that will be assigned the URI <emphasis
        role="bold">http://www.engageinteractive.com/person/</emphasis> and
        these elements and/or attributes are different from elements and/or
        attributes that are assigned the URI <emphasis
        role="bold">http://www.engageinteractive.com/book/</emphasis>
        </emphasis></para>

        <para>It also says that:</para>

        <para><emphasis>We will use the prefix "person" as shorthand for the
        URI <emphasis
        role="bold">http://www.engageinteractive.com/person/</emphasis>, and
        we will use the abbreviation "book" as shorthand for the URI <emphasis
        role="bold">http://www.engageinteractive.com/book/</emphasis>
        </emphasis></para>

        <para>It is then a simple task of placing the prefixes <emphasis
        role="bold">person:</emphasis> and <emphasis
        role="bold">book:</emphasis> before all corresponding elements and
        attributes. A namespace aware XML parser will be able to parse and
        differentiate between the elements named
        <computeroutput>&lt;person:title&gt;</computeroutput> and
        <computeroutput>&lt;book:title&gt;</computeroutput></para>
      </section>

      <section>
        <title>Default Namespace</title>

        <para>If an XML document does not contain a namespace declaration,
        then it is assumed that all elements in the document belong to the
        <emphasis>default namespace</emphasis>. The default namespace is
        <emphasis role="bold">null</emphasis> unless defined by the
        user.</para>

        <para>If you would like to specify a user-defined default namespace,
        <emphasis>omit the namespace prefix in your xmlns
        declaration</emphasis>:</para>

        <para><programlisting>xmlns="http://www.engageinteractive.com/this.is.a.default.namespace"</programlisting></para>

        <para><remark>Note: Default namespaces do not apply to
        attributes.</remark></para>
      </section>

      <section>
        <title>Local Name</title>

        <para>When an XML document uses namespaces, the tag name of an element
        or attribute (i.e., the part following the namespace prefix) is
        referred to as its <emphasis>Local Name</emphasis>.</para>

        <para>The local name of the
        <computeroutput>&lt;person:individual&gt;</computeroutput> element,
        for instance, is "individual".</para>
      </section>

      <section>
        <title>Qualified Name</title>

        <para>The concatenated namespace prefix and local name are referred to
        as the <emphasis>Qualified Name</emphasis>, or
        <emphasis>qname</emphasis>.</para>

        <para>The qualified name of
        <computeroutput>&lt;person:individual&gt;</computeroutput> element,
        for instance, is "person:individual"</para>
      </section>

      <section>
        <title>DOM and XML Namespaces</title>

        <para>The DOM specifies a number of namespace aware methods, such as
        <function>getElementsByTagNameNS</function>, which allows you to
        specify the qualified name of the element that you are searching
        for.</para>
      </section>
    </section>

    <section>
      <title>DOMIT! and XML Namespaces</title>

      <para>DOMIT! (although not DOMIT! Lite) is compliant with the XML
      Namespace specification. It implements the following methods:</para>

      <section>
        <title><function>setNamespaceAwareness</function></title>

        <para>To enable DOMIT! to process namespace data, invoke the
        <function>setNamespaceAwareness</function> method before populating
        your XML document.</para>

        <para><programlisting>$xmldoc-&gt;setNamespaceAwareness(true);</programlisting></para>
      </section>

      <section>
        <title><function>declareNamespace</function></title>

        <para>The <function>declareNamespace</function> method allows you to
        make a namespace declaration at the level of the calling
        element.</para>

        <para>You must specify two parameters:</para>

        <itemizedlist>
          <listitem>
            <para>a namespace prefix</para>
          </listitem>

          <listitem>
            <para>a namespace URI</para>
          </listitem>
        </itemizedlist>

        <para>The following creates a namespace declaration with a prefix of
        "domit" at the document element level:</para>

        <para><programlisting>$xmldoc-&gt;documentElement-&gt;declareNamespace('domit', 'http://www.engageinteractive.com/domit/');</programlisting></para>

        <para>The resulting namespace declaration would look like this:</para>

        <para><programlisting>xmlns:domit="http://www.engageinteractive.com/domit/"</programlisting></para>
      </section>

      <section>
        <title><function>declareDefaultNamespace</function></title>

        <para>The <function>declareDefaultNamespace</function> method allows
        you to make a default namespace declaration at the level of the
        calling element.</para>

        <para><programlisting>$xmldoc-&gt;documentElement-&gt;declareDefaultNamespace('http://www.foo.com/a.default.namespace');</programlisting></para>

        <para>The resulting ndefault amespace declaration would look like
        this:</para>

        <para><programlisting>xmlns="http://www.foo.com/a.default.namespace"</programlisting></para>

        <para>To reset the default namespace back to its original <emphasis
        role="bold">null</emphasis> value, pass in an empty string to the
        <function>declareDefaultNamespace</function> method:</para>

        <para><programlisting>$xmldoc-&gt;documentElement-&gt;declareDefaultNamespace("");</programlisting></para>
      </section>

      <section>
        <title><function>getNamespaceDeclarationsInScope</function></title>

        <para>The <function>getNamespaceDeclarationsInScope</function> method
        returns an associative array of all namespace declarations that are in
        scope for the calling element.</para>

        <para><programlisting>//acquire array of namespace declarations in scope
$nsMap = $xmldoc-&gt;documentElement-&gt;firstChild-&gt;getNamespaceDeclarationsInScope();

//echo to browser
print "&lt;pre&gt;";
print_r($nsMap);
print "&lt;/pre&gt;";</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>Array
(
    [http://www.engageinteractive.com/person/] =&gt; person
    [http://www.engageinteractive.com/book/] =&gt; book
)</programlisting></para>
      </section>

      <section>
        <title><function>getDefaultNamespaceDeclaration</function></title>

        <para>The <function>getDefaultNamespaceDeclaration</function> method
        returns a string containing the default namespace declaration in scope
        for for the calling element.</para>

        <para><programlisting>echo $xmldoc-&gt;documentElement-&gt;childNodes[2]-&gt;firstChild-&gt;getDefaultNamespaceDeclaration();</programlisting></para>

        <para>The result is an empty string:</para>

        <para><programlisting></programlisting></para>
      </section>

      <section>
        <title><function>copyNamespaceDeclarationsLocally</function></title>

        <para>A common problem with namespaces occurs when an element is moved
        to another location in a document, or copied to another DOM
        document.</para>

        <para>If the node being copied is not the document element, and the
        namespace declarations in scope for that element are declared higher
        up in the DOM tree (for example, in the document element), then the
        namespace declarations can be lost.</para>

        <para>In the following XML, for instance, if the
        <computeroutput>&lt;book:book&gt;</computeroutput> element were to be
        copied to another DOM document, the namespace declarations in the
        document element might not accompany the element:</para>

        <para><programlisting> &lt;?xml version="1.0"?&gt;
&lt;person:individual person:gender="m"
        xmlns:person="http://www.engageinteractive.com/person/"
        xmlns:book="http://www.engageinteractive.com/book/"&gt;
  &lt;person:name&gt;George Henry III&lt;/person:name&gt;
  &lt;person:title&gt;Duke of Fredericton&lt;/person:title&gt;
  &lt;person:books&gt;
    &lt;book:book&gt;
      &lt;book:title&gt;Transcendence Through XML&lt;/book:title&gt;
    &lt;/book:book&gt;
  &lt;/person:books&gt;
&lt;/person:individual&gt;</programlisting></para>

        <para>The <function>copyNamespaceDeclarationsLocally</function> method
        addresses this problem, by forcing all namespace delarations that are
        in scope for the element to be explicitly duplicated on the element
        itself.</para>

        <para><programlisting>//get reference to book:book node
$bookNode =&amp; $xmldoc-&gt;documentElement-&gt;childNodes[2]-&gt;firstChild;

//copy namespace declarations
$bookNode-&gt;copyNamespaceDeclarationsLocally();

//echo to browser
echo $bookNode-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;book:book xmlns:person="http://www.engageinteractive.com/person/" xmlns:book="http://www.engageinteractive.com/book/"&gt;
  &lt;book:title&gt;Transcendence Through XML&lt;/book:title&gt;
&lt;/book:book&gt;</programlisting></para>
      </section>

      <section>
        <title><function>createElementNS</function></title>

        <para>The <function>createElementNS</function> method is used to
        create a namespace compliant element.</para>

        <para><function>createElementNS</function> takes two
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the element</para>
          </listitem>

          <listitem>
            <para>its qualified name</para>
          </listitem>
        </itemizedlist>

        <para>The following example will create the
        <computeroutput>&lt;book:title&gt;</computeroutput> element:</para>

        <para><programlisting>//create namespace compliant element
$myElement =&amp; $xmldoc-&gt;createElementNS('http://www.engageinteractive.com/book/', 'book:title');

//echo to browser
echo $myElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;book:title /&gt;</programlisting></para>

        <para><remark>Note that using the <function>createElement</function>
        method will not create an element properly when namespace awareness is
        enabled.</remark></para>
      </section>

      <section>
        <title><function>getElementsByTagNameNS</function></title>

        <para>The <function>getElementsByTagNameNS</function> method is a
        namespace compliant version of
        <function>getElementsByTagName</function>. It allows you to search for
        elements in an XML document by specifying:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the element</para>
          </listitem>

          <listitem>
            <para>the local name</para>
          </listitem>
        </itemizedlist>

        <para>The following example matches the
        <computeroutput>&lt;book:title&gt;</computeroutput> element:</para>

        <para><programlisting>//find book:title element
$myNodeList =&amp; $xmldoc-&gt;getElementsByTagNameNS('http://www.engageinteractive.com/book/', 'title');

//echo to browser
echo $myNodeList-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;book:title&gt;Transcendence Through XML&lt;/book:title&gt;</programlisting></para>
      </section>

      <section>
        <title><function>createAttributeNS</function></title>

        <para>The <function>createAttributeNS</function> method is the
        namespace equivalent of <function>createAttribute</function>. It
        enables you to create a new, namespace compliant, attribute
        node.</para>

        <para><function>createAttributeNS</function> takes two
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the attribute</para>
          </listitem>

          <listitem>
            <para>the local name</para>
          </listitem>
        </itemizedlist>

        <para>The following example creates a new attribute named
        "book:language", with a value of "en"</para>

        <para><programlisting>//create namespace compliant attribute
$myAttr =&amp; $xmldoc-&gt;createAttributeNS('http://www.engageinteractive.com/book/', 'language', 'en');

//echo to browser
echo $myAttr-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>book:language='en'</programlisting></para>
      </section>

      <section>
        <title><function>hasAttributeNS</function> and
        <function>getAttributeNS</function></title>

        <para>The <function>hasAttributeNS</function> and
        <function>getAttributeNS</function> methods are namespace compliant
        versions of <function>hasAttribute</function> and
        <function>getAttribute</function>. Both methods take as
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the attribute</para>
          </listitem>

          <listitem>
            <para>the local name</para>
          </listitem>
        </itemizedlist>

        <para>The following example checks if an attribute named 'gender' with
        a namespace URI of 'http://www.engageinteractive.com/person/' exists
        in the document element, and echoes the value to the browser:</para>

        <para><programlisting>//set variables for namespace URI and local name
$URI = 'http://www.engageinteractive.com/person/';
$localName = 'gender';

//determine if atrribute exists
if ($xmldoc-&gt;documentElement-&gt;hasAttributeNS($URI, $localName)) {
  
  //echo to browser
  echo $xmldoc-&gt;documentElement-&gt;getAttributeNS($URI, $localName);
}</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>m</programlisting></para>
      </section>

      <section>
        <title><function>setAttributeNS</function></title>

        <para>The <function>setAttributeNS</function> method is a namespace
        compliant version of <function>setAttribute</function>. It creates a
        new namespace compliant attribute for the calling element, or
        overwrites the value of the attibute if one already exists.</para>

        <para><function>setAttributeNS</function> takes three
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the attribute</para>
          </listitem>

          <listitem>
            <para>the qualified name</para>
          </listitem>

          <listitem>
            <para>the value of the attribute</para>
          </listitem>
        </itemizedlist>

        <para>The following example sets a new attribute on the
        &lt;book:title&gt; element.</para>

        <para><programlisting>//find book:title element
$myNodeList =&amp; $xmldoc-&gt;getElementsByTagNameNS('http://www.engageinteractive.com/book/', 'title');

//get first match
$myElement =&amp; $myNodeList-&gt;item(0);

//add attribute named "book:language" to the element
$myElement-&gt;setAttributeNS('http://www.engageinteractive.com/book/', 'book:language', 'en');

//echo to browser
echo $myElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;book:title book:language="en"&gt;Transcendence Through XML&lt;/book:title&gt;</programlisting></para>
      </section>

      <section>
        <title><function>getAttributeNodeNS</function> and
        <function>setAttributeNodeNS</function></title>

        <para>The <function>getAttributeNodeNS</function> and
        s<function>etAttributeNodeNS</function> methods are namespace
        compliant versions of <function>getAttributeNode</function> and
        <function>setAttributeNode</function>.</para>

        <para><function>getAttributeNodeNS</function> takes two
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the attribute</para>
          </listitem>

          <listitem>
            <para>the local name</para>
          </listitem>
        </itemizedlist>

        <para><function>setAttributeNodeNS</function> takes a single parameter
        -- a reference to the node to be added/set.</para>

        <para>The following example echoes the value of the "gender" attribute
        and then changes it to "f":</para>

        <para><programlisting>//get the attribute node named "gender" in the document element
$attrNode =&amp; $xmldoc-&gt;documentElement-&gt;getAttributeNodeNS('http://www.engageinteractive.com/person/', 'gender');

//echo value of attr node
echo "original value of gender node is: " . $attrNode-&gt;getValue();

//create a new attribute node
$myAttr =&amp; $xmldoc-&gt;createAttributeNS('http://www.engageinteractive.com/person/', 'gender', 'f');

//overwrite existing attr with new one
$xmldoc-&gt;documentElement-&gt;setAttributeNodeNS();

//echo to browser
echo $xmldoc-&gt;documentElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;person:individual person:gender="f"
        xmlns:person="http://www.engageinteractive.com/person/"
        xmlns:book="http://www.engageinteractive.com/book/"&gt;
  &lt;person:name&gt;George Henry III&lt;/person:name&gt;
  &lt;person:title&gt;Duke of Fredericton&lt;/person:title&gt;
  &lt;person:books&gt;
    &lt;book:book&gt;
      &lt;book:title&gt;Transcendence Through XML&lt;/book:title&gt;
    &lt;/book:book&gt;
  &lt;/person:books&gt;
&lt;/person:individual&gt;</programlisting></para>
      </section>

      <section>
        <title><function>removeAttributeNS</function></title>

        <para>The <function>removeAttributeNS</function> method is the
        namespace counterpart to <function>removeAttribute</function>. It
        enabled you to remove an attribute from an element.</para>

        <para><function>removeAttributeNS</function> takes two
        parameters:</para>

        <itemizedlist>
          <listitem>
            <para>the namespace URI of the attribute</para>
          </listitem>

          <listitem>
            <para>the local name</para>
          </listitem>
        </itemizedlist>

        <para>The following example removes the "gender" attribute from the
        document element:</para>

        <para><programlisting>//remove "gender" attribute from document element
$xmldoc-&gt;documentElement-&gt;removeAttributeNS('http://www.engageinteractive.com/person/', 'gender');

//echo to browser
echo $xmldoc-&gt;documentElement-&gt;toNormalizedString(true);</programlisting></para>

        <para>The result is:</para>

        <para><programlisting>&lt;person:individual
        xmlns:person="http://www.engageinteractive.com/person/"
        xmlns:book="http://www.engageinteractive.com/book/"&gt;
  &lt;person:name&gt;George Henry III&lt;/person:name&gt;
  &lt;person:title&gt;Duke of Fredericton&lt;/person:title&gt;
  &lt;person:books&gt;
    &lt;book:book&gt;
      &lt;book:title&gt;Transcendence Through XML&lt;/book:title&gt;
    &lt;/book:book&gt;
  &lt;/person:books&gt;
&lt;/person:individual&gt;</programlisting></para>
      </section>
    </section>
  </chapter>

  <chapter>
    <title>XPath</title>

    <para>DOMIT! now has experimental <ulink
    url="http://www.w3.org/TR/xpath">XPath</ulink> support.</para>

    <para>XPath is a syntax for locating nodes in an XML tree using
    "path"-like expressions. A good introductory tutorial on XPath can be
    found at: <ulink
    url="http://www.w3schools.com/xpath/">http://www.w3schools.com/xpath/</ulink></para>

    <section>
      <title>XPath Overview</title>

      <para><remark>Add content here!</remark></para>
    </section>

    <section>
      <title><function>selectNodes</function></title>

      <para>DOMIT! implements XPath calls through the
      <function>selectNodes</function> method. Not all of the specification is
      supported currently.</para>

      <para><function>selectNodes</function> can be called from any XML
      document or element node. It converts an XPath expression into a node
      list or single node that matches the specified pattern. For
      example:</para>

      <para><programlisting>$nodeList =&amp; $xmldoc-&gt;selectNodes("/book/chapter[@id='1234']");</programlisting></para>

      <para>The above example will return a node list containing all nodes in
      the XML document:</para>

      <itemizedlist>
        <listitem>
          <para>whose document element is named 'book', which has</para>
        </listitem>

        <listitem>
          <para>a child node named 'chapter', which has</para>
        </listitem>

        <listitem>
          <para>an 'id' attribute with a value of '1234'</para>
        </listitem>
      </itemizedlist>

      <para>If you would like a single node to be returned by
      <function>selectNodes</function>, rather than the entire node list of
      matching elements, you can specify the index of the requested node by
      passing an integer as the second parameter of
      <function>selectNodes</function>.</para>

      <para>The index is 1-based. The following example will return the first
      node matching the XPath expression:</para>

      <para><programlisting>$nodeList =&amp; $xmldoc-&gt;selectNodes("/book/chapter[@id='1234']", 1);</programlisting></para>

      <para><remark>Add content here!</remark></para>
    </section>
  </chapter>

  <chapter>
    <title>DOMIT! Roadmap</title>

    <para>Some of the plans for DOMIT include:</para>

    <itemizedlist>
      <listitem>
        <para>UTF-8 support</para>
      </listitem>

      <listitem>
        <para>fuller XPath support</para>
      </listitem>

      <listitem>
        <para>OneDOM: a generic wrapper for DOMIT! and the PHP DOM_XML
        library</para>
      </listitem>
    </itemizedlist>
  </chapter>

  <chapter>
    <title>Contributing to DOMIT!</title>

    <para>DOMIT! has only been made possible through the suggestions, bug
    reports, and code submissions of others.</para>

    <para>If you would like to contribute to DOMIT! or join the DOMIT! team,
    please email <email>johnkarl@nbnet.nb.ca</email></para>
  </chapter>
</book>