<reference id="ref.xml">
  <title>XML parser functions</title>
  <titleabbrev>XML</titleabbrev>

  <partintro>
   <sect1 id="xml.partintro">
    <title>Introduction</title>
    <sect2 id="xml.intro">
     <title>About XML</title>
     <para>
      XML (eXtensible Markup Language) is a data format for structured
      document interchange on the Web.  It is a standard defined by
      The World Wide Web consortium (W3C).  Information about XML and
      related technologies can be found at <ulink
      url="&url.xml;">&url.xml;</ulink>.
     </para>
    </sect2>
    <sect2 id="xml.install">
     <title>Installation</title>
     <para>
      This extension uses <productname>expat</productname>, which can
      be found at <ulink url="&url.expat;">&url.expat;</ulink>.  The
      Makefile that comes with expat does not build a library by
      default, you can use this make rule for that:
      <programlisting role="makefile">
libexpat.a: $(OBJS)
    ar -rc $@ $(OBJS)
    ranlib $@
      </programlisting>
      A source RPM package of expat can be found at <ulink
      url="&url.expat.rpm;">&url.expat.rpm;</ulink>.
     </para>
     <para>
      Note that if you are using Apache-1.3.7 or later, you already
      have the required expat library.  Simply configure PHP using
      <option role="configure">--with-xml</option> (without any
      additional path) and it will automatically use the expat library
      built into Apache.
     </para>
     <para>
      On UNIX, run <command>configure</command> with the <option
      role="configure">--with-xml</option> option.  The
      <productname>expat</productname> library should be installed
      somewhere your compiler can find it.  If you compile PHP as a
      module for Apache 1.3.9 or later, PHP will automatically use the
      bundled <productname>expat</productname> library from Apache.
      You may need to set <envar>CPPFLAGS</envar> and
      <envar>LDFLAGS</envar> in your environment before running
      configure if you have installed expat somewhere exotic.
     </para>
     <para>
      Build PHP.  <emphasis>Tada!</emphasis>  That should be it.
     </para>
    </sect2>

    <sect2 id="xml.about">
     <title>About This Extension</title>
     <para>
      This PHP extension implements support for James Clark's
      <productname>expat</productname> in PHP.  This toolkit lets you
      parse, but not validate, XML documents.  It supports three
      source <link linkend="xml.encoding">character encodings</link>
      also provided by PHP: <literal>US-ASCII</literal>,
      <literal>ISO-8859-1</literal> and <literal>UTF-8</literal>.
      <literal>UTF-16</literal> is not supported.
     </para>
     <para>
      This extension lets you <link
      linkend="function.xml-parser-create">create XML parsers</link>
      and then define <emphasis>handlers</emphasis> for different XML
      events.  Each XML parser also has a few <link
      linkend="function.xml-parser-set-option">parameters</link> you
      can adjust.
     </para>
     <para>
      The XML event handlers defined are:
      <table>
       <title>Supported XML handlers</title>
       <tgroup cols="2">
    <thead>
     <row>
      <entry>PHP function to set handler</entry>
      <entry>Event description</entry>
     </row>
    </thead>
    <tbody>
     <row>
      <entry><function>xml_set_element_handler</function></entry>
      <entry>
       Element events are issued whenever the XML parser
       encounters start or end tags.  There are separate handlers
       for start tags and end tags.
      </entry>
     </row>
     <row>
      <entry>
       <function>xml_set_character_data_handler</function>
      </entry>
      <entry>
       Character data is roughly all the non-markup contents of
       XML documents, including whitespace between tags.  Note
       that the XML parser does not add or remove any whitespace,
       it is up to the application (you) to decide whether
       whitespace is significant.
      </entry>
     </row>
     <row>
      <entry>
       <function>xml_set_processing_instruction_handler</function>
      </entry>
      <entry>
       PHP programmers should be familiar with processing
       instructions (PIs) already.  &lt;?php ?&gt; is a processing
       instruction, where <replaceable>php</replaceable> is called
       the "PI target".  The handling of these are
       application-specific, except that all PI targets starting
       with "XML" are reserved.
      </entry>
     </row>
     <row>
      <entry><function>xml_set_default_handler</function></entry>
      <entry>
       What goes not to another handler goes to the default
       handler.  You will get things like the XML and document
       type declarations in the default handler.
      </entry>
     </row>
     <row>
      <entry>
       <function>xml_set_unparsed_entity_decl_handler</function>
      </entry>
      <entry>
       This handler will be called for declaration of an unparsed
       (NDATA) entity.
      </entry>
     </row>
     <row>
      <entry>
       <function>xml_set_notation_decl_handler</function>
      </entry>
      <entry>
       This handler is called for declaration of a notation.
      </entry>
     </row>
     <row>
      <entry>
       <function>xml_set_external_entity_ref_handler</function>
      </entry>
      <entry>
       This handler is called when the XML parser finds a
       reference to an external parsed general entity.  This can
       be a reference to a file or URL, for example.  See <link
       linkend="example.xml-external-entity">the external entity
       example</link> for a demonstration.
      </entry>
     </row>
    </tbody>
       </tgroup>
      </table>
     </para>
    </sect2>

    <sect2 id="xml.case-folding">
     <title>Case Folding</title>
     <para>
      The element handler functions may get their element names
      <glossterm>case-folded</glossterm>.  Case-folding is defined by
      the XML standard as "a process applied to a sequence of
      characters, in which those identified as non-uppercase are
      replaced by their uppercase equivalents".  In other words, when
      it comes to XML, case-folding simply means uppercasing.
     </para>
     <para>
      By default, all the element names that are passed to the handler
      functions are case-folded.  This behaviour can be queried and
      controlled per XML parser with the
      <function>xml_parser_get_option</function> and
      <function>xml_parser_set_option</function> functions,
      respectively.
     </para>
    </sect2>

    <sect2 id="xml.error-codes">
     <title>Error Codes</title>
     <para>
      The following constants are defined for XML error codes (as
      returned by <function>xml_parse</function>):
      <simplelist>
       <member>XML_ERROR_NONE</member>
       <member>XML_ERROR_NO_MEMORY</member>
       <member>XML_ERROR_SYNTAX</member>
       <member>XML_ERROR_NO_ELEMENTS</member>
       <member>XML_ERROR_INVALID_TOKEN</member>
       <member>XML_ERROR_UNCLOSED_TOKEN</member>
       <member>XML_ERROR_PARTIAL_CHAR</member>
       <member>XML_ERROR_TAG_MISMATCH</member>
       <member>XML_ERROR_DUPLICATE_ATTRIBUTE</member>
       <member>XML_ERROR_JUNK_AFTER_DOC_ELEMENT</member>
       <member>XML_ERROR_PARAM_ENTITY_REF</member>
       <member>XML_ERROR_UNDEFINED_ENTITY</member>
       <member>XML_ERROR_RECURSIVE_ENTITY_REF</member>
       <member>XML_ERROR_ASYNC_ENTITY</member>
       <member>XML_ERROR_BAD_CHAR_REF</member>
       <member>XML_ERROR_BINARY_ENTITY_REF</member>
       <member>XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF</member>
       <member>XML_ERROR_MISPLACED_XML_PI</member>
       <member>XML_ERROR_UNKNOWN_ENCODING</member>
       <member>XML_ERROR_INCORRECT_ENCODING</member>
       <member>XML_ERROR_UNCLOSED_CDATA_SECTION</member>
       <member>XML_ERROR_EXTERNAL_ENTITY_HANDLING</member>
      </simplelist>
     </para>
    </sect2>
    <sect2 id="xml.encoding">
     <title>Character Encoding</title>
     <para>
      PHP's XML extension supports the <ulink
      url="&url.unicode;">Unicode</ulink> character set through
      different <glossterm>character encoding</glossterm>s.  There are
      two types of character encodings, <glossterm>source
      encoding</glossterm> and <glossterm>target encoding</glossterm>.
      PHP's internal representation of the document is always encoded
      with <literal>UTF-8</literal>.
     </para>
     <para>
      Source encoding is done when an XML document is <link
      linkend="function.xml-parse">parsed</link>.  Upon <link
      linkend="function.xml-parser-create">creating an XML
      parser</link>, a source encoding can be specified (this encoding
      can not be changed later in the XML parser's lifetime).  The
      supported source encodings are <literal>ISO-8859-1</literal>,
      <literal>US-ASCII</literal> and <literal>UTF-8</literal>.  The
      former two are single-byte encodings, which means that each
      character is represented by a single byte.
      <literal>UTF-8</literal> can encode characters composed by a
      variable number of bits (up to 21) in one to four bytes.  The
      default source encoding used by PHP is
      <literal>ISO-8859-1</literal>.
     </para>
     <para>
      Target encoding is done when PHP passes data to XML handler
      functions.  When an XML parser is created, the target encoding
      is set to the same as the source encoding, but this may be
      changed at any point.  The target encoding will affect character
      data as well as tag names and processing instruction targets.
     </para>
     <para>
      If the XML parser encounters characters outside the range that
      its source encoding is capable of representing, it will return
      an error.  
     </para>
     <para>
      If PHP encounters characters in the parsed XML document that can
      not be represented in the chosen target encoding, the problem
      characters will be "demoted".  Currently, this means that such
      characters are replaced by a question mark.
     </para>
    </sect2>
   </sect1>

   <sect1 id="xml.examples">
    <title>Some Examples</title>
    <para>
     Here are some example PHP scripts parsing XML documents.
    </para>
    <sect2 id="example.xml-structure">
     <title>XML Element Structure Example</title>
     <para>
      This first example displays the stucture of the start elements in
      a document with indentation.
      <example>
       <title>Show XML Element Structure</title>
       <programlisting role="php">
$file = "data.xml";
$depth = array();

function startElement($parser, $name, $attrs) {
    global $depth;
    for ($i = 0; $i &lt; $depth[$parser]; $i++) {
        print "  ";
    }
    print "$name\n";
    $depth[$parser]++;
}

function endElement($parser, $name) {
    global $depth;
    $depth[$parser]--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
       </programlisting>
      </example>
     </para>
    </sect2>

    <sect2 id="example.xml-map-tags">
     <title>XML Tag Mapping Example</title>
     <para>
      <example>
       <title>Map XML to HTML</title>
       <para>
    This example maps tags in an XML document directly to HTML
    tags.  Elements not found in the "map array" are ignored.  Of
    course, this example will only work with a specific XML
    document type.
    <programlisting role="php">
$file = "data.xml";
$map_array = array(
    "BOLD"     =&gt; "B",
    "EMPHASIS" =&gt; "I",
    "LITERAL"  =&gt; "TT"
);

function startElement($parser, $name, $attrs) {
    global $map_array;
    if ($htmltag = $map_array[$name]) {
        print "&lt;$htmltag&gt;";
    }
}

function endElement($parser, $name) {
    global $map_array;
    if ($htmltag = $map_array[$name]) {
        print "&lt;/$htmltag&gt;";
    }
}

function characterData($parser, $data) {
    print $data;
}

$xml_parser = xml_parser_create();
// use case-folding so we are sure to find the tag in $map_array
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
    </programlisting>
       </para>
      </example>
     </para>
    </sect2>

    <sect2 id="example.xml-external-entity">
     <title>XML External Entity Example</title>
     <para>
      This example highlights XML code.  It illustrates how to use an
      external entity reference handler to include and parse other
      documents, as well as how PIs can be processed, and a way of
      determining "trust" for PIs containing code.
     </para>
     <para>
      XML documents that can be used for this example are found below
      the example (<filename>xmltest.xml</filename> and
      <filename>xmltest2.xml</filename>.)
     </para>
     <para>
      <example>
       <title>External Entity Example</title>
       <programlisting role="php">
$file = "xmltest.xml";

function trustedFile($file) {
    // only trust local files owned by ourselves
    if (!eregi("^([a-z]+)://", $file) 
        &amp;&amp; fileowner($file) == getmyuid()) {
            return true;
    }
    return false;
}

function startElement($parser, $name, $attribs) {
    print "&amp;lt;&lt;font color=\"#0000cc\"&gt;$name&lt;/font&gt;";
    if (sizeof($attribs)) {
        while (list($k, $v) = each($attribs)) {
            print " &lt;font color=\"#009900\"&gt;$k&lt;/font&gt;=\"&lt;font 
                   color=\"#990000\"&gt;$v&lt;/font&gt;\"";
        }
    }
    print "&amp;gt;";
}

function endElement($parser, $name) {
    print "&amp;lt;/&lt;font color=\"#0000cc\"&gt;$name&lt;/font&gt;&amp;gt;";
}

function characterData($parser, $data) {
    print "&lt;b&gt;$data&lt;/b&gt;";
}

function PIHandler($parser, $target, $data) {
    switch (strtolower($target)) {
        case "php":
            global $parser_file;
            // If the parsed document is "trusted", we say it is safe
            // to execute PHP code inside it.  If not, display the code
            // instead.
            if (trustedFile($parser_file[$parser])) {
                eval($data);
            } else {
                printf("Untrusted PHP code: &lt;i&gt;%s&lt;/i&gt;", 
                        htmlspecialchars($data));
            }
            break;
    }
}

function defaultHandler($parser, $data) {
    if (substr($data, 0, 1) == "&amp;" &amp;&amp; substr($data, -1, 1) == ";") {
        printf('&lt;font color="#aa00aa"&gt;%s&lt;/font&gt;', 
                htmlspecialchars($data));
    } else {
        printf('&lt;font size="-1"&gt;%s&lt;/font&gt;', 
                htmlspecialchars($data));
    }
}

function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId,
                                  $publicId) {
    if ($systemId) {
        if (!list($parser, $fp) = new_xml_parser($systemId)) {
            printf("Could not open entity %s at %s\n", $openEntityNames,
                   $systemId);
            return false;
        }
        while ($data = fread($fp, 4096)) {
            if (!xml_parse($parser, $data, feof($fp))) {
                printf("XML error: %s at line %d while parsing entity %s\n",
                       xml_error_string(xml_get_error_code($parser)),
                       xml_get_current_line_number($parser), $openEntityNames);
                xml_parser_free($parser);
                return false;
            }
        }
        xml_parser_free($parser);
        return true;
    }
    return false;
}


function new_xml_parser($file) {
    global $parser_file;

    $xml_parser = xml_parser_create();
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");
    xml_set_processing_instruction_handler($xml_parser, "PIHandler");
    xml_set_default_handler($xml_parser, "defaultHandler");
    xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");
    
    if (!($fp = @fopen($file, "r"))) {
        return false;
    }
    if (!is_array($parser_file)) {
        settype($parser_file, "array");
    }
    $parser_file[$xml_parser] = $file;
    return array($xml_parser, $fp);
}

if (!(list($xml_parser, $fp) = new_xml_parser($file))) {
    die("could not open XML input");
}

print "&lt;pre&gt;";
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d\n",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
print "&lt;/pre&gt;";
print "parse complete\n";
xml_parser_free($xml_parser);

?&gt;
       </programlisting>
      </example>
     </para>
     <para id="example.xml-xmltest.xml">
      <example>
       <title>xmltest.xml</title>
       <programlisting role="xml">
&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [
&lt;!ENTITY plainEntity "FOO entity"&gt;
&lt;!ENTITY systemEntity SYSTEM "xmltest2.xml"&gt;
]&gt;
&lt;chapter&gt;
 &lt;TITLE&gt;Title &amp;plainEntity;&lt;/TITLE&gt;
 &lt;para&gt;
  &lt;informaltable&gt;
   &lt;tgroup cols="3"&gt;
    &lt;tbody&gt;
     &lt;row&gt;&lt;entry&gt;a1&lt;/entry&gt;&lt;entry morerows="1"&gt;b1&lt;/entry&gt;&lt;entry&gt;c1&lt;/entry&gt;&lt;/row&gt;
     &lt;row&gt;&lt;entry&gt;a2&lt;/entry&gt;&lt;entry&gt;c2&lt;/entry&gt;&lt;/row&gt;
     &lt;row&gt;&lt;entry&gt;a3&lt;/entry&gt;&lt;entry&gt;b3&lt;/entry&gt;&lt;entry&gt;c3&lt;/entry&gt;&lt;/row&gt;
    &lt;/tbody&gt;
   &lt;/tgroup&gt;
  &lt;/informaltable&gt;
 &lt;/para&gt;
 &amp;systemEntity;
 &lt;sect1 id="about"&gt;
  &lt;title&gt;About this Document&lt;/title&gt;
  &lt;para&gt;
   &lt;!-- this is a comment --&gt;
   &lt;?php print 'Hi!  This is PHP version '.phpversion(); ?&gt;
  &lt;/para&gt;
 &lt;/sect1&gt;
&lt;/chapter&gt;
       </programlisting>
      </example>
     </para>
     <para id="example.xml-xmltest2.xml">
      This file is included from <filename>xmltest.xml</filename>:
      <example>
       <title>xmltest2.xml</title>
       <programlisting role="xml">
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE foo [
&lt;!ENTITY testEnt "test entity"&gt;
]&gt;
&lt;foo&gt;
   &lt;element attrib="value"/&gt;
   &amp;testEnt;
   &lt;?php print "This is some more PHP code being executed."; ?&gt;
&lt;/foo&gt;
       </programlisting>
      </example>
     </para>
    </sect2>
   </sect1>
  </partintro>

  <refentry id="function.xml-parser-create">
   <refnamediv>
    <refname>xml_parser_create</refname>
    <refpurpose>create an XML parser</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int <function>xml_parser_create</function></funcdef>
      <paramdef>string 
       <parameter><optional>encoding</optional></parameter>
      </paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>encoding</parameter> (optional)</term>
       <listitem>
    <para>
     Which character encoding the parser should use.  The
     following character encodings are supported:
     <simplelist>
      <member><literal>ISO-8859-1</literal> (default)</member>
      <member><literal>US-ASCII</literal></member>
      <member><literal>UTF-8</literal></member>
     </simplelist>
    </para>
       </listitem>
      </varlistentry>
     </variablelist>
     This function creates an XML parser and returns a handle for use
     by other XML functions.  Returns <literal>false</literal> on
     failure.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-object">
   <refnamediv>
    <refname>xml_set_object</refname>
    <refpurpose>Use XML Parser within an object</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>void <function>xml_set_object</function></funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>object <parameter>&amp;object</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     This function allows to use <parameter>parser</parameter> inside
     <parameter>object</parameter>. All callback functions could be
     set with <function>xml_set_element_handler</function> etc and
     assumed to be methods of <parameter>object</parameter>.
    </para>
    <programlisting role="php">
&lt;?php
class xml  {
var $parser;

function xml() {
    $this-&gt;parser = xml_parser_create();
    xml_set_object($this-&gt;parser,&amp;$this);
    xml_set_element_handler($this-&gt;parser,"tag_open","tag_close");
    xml_set_character_data_handler($this-&gt;parser,"cdata");
}

function parse($data) { 
    xml_parse($this-&gt;parser,$data);
}

function tag_open($parser,$tag,$attributes) { 
    var_dump($parser,$tag,$attributes); 
}

function cdata($parser,$cdata) { 
    var_dump($parser,$cdata);
}

function tag_close($parser,$tag) { 
    var_dump($parser,$tag); 
}

} // end of class xml

$xml_parser = new xml();
$xml_parser-&gt;parse("&lt;A ID=\"hallo\"&gt;PHP&lt;/A&gt;");
?&gt;
    </programlisting>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-element-handler">
   <refnamediv>
    <refname>xml_set_element_handler</refname>
    <refpurpose>set up start and end element handlers</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_element_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string 
       <parameter>startElementHandler</parameter>
      </paramdef>
      <paramdef>string 
       <parameter>endElementHandler</parameter>
      </paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the element handler functions for the XML parser
     <parameter>parser</parameter>.
     <parameter>startElementHandler</parameter> and
     <parameter>endElementHandler</parameter> are strings containing
     the names of functions that must exist when
     <function>xml_parse</function> is called for
     <parameter>parser</parameter>.
    </para>
    <para>
     The function named by <parameter>startElementHandler</parameter>
     must accept three parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>startElementHandler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>name</parameter></paramdef>
       <paramdef>array <parameter>attribs</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term> 
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the
     handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>name</parameter></term>
       <listitem>
    <simpara>
     The second parameter, <parameter>name</parameter>, contains
     the name of the element for which this handler is called.  If
     <link linkend="xml.case-folding">case-folding</link> is in
     effect for this parser, the element name will be in uppercase
     letters.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>attribs</parameter></term>
       <listitem>
    <simpara>
     The third parameter, <parameter>attribs</parameter>, contains
     an associative array with the element's attributes (if any).
     The keys of this array are the attribute names, the values
     are the attribute values.  Attribute names are <link
     linkend="xml.case-folding">case-folded</link> on the same
     criteria as element names.  Attribute values are
     <emphasis>not</emphasis> case-folded.
    </simpara>
    <simpara>
     The original order of the attributes can be retrieved by
     walking through <parameter>attribs</parameter> the normal
     way, using <function>each</function>.  The first key in the
     array was the first attribute, and so on.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     The function named by <parameter>endElementHandler</parameter>
     must accept two parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>endElementHandler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>name</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term> 
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the
     handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>name</parameter></term>
       <listitem>
    <simpara>
     The second parameter, <parameter>name</parameter>, contains
     the name of the element for which this handler is called.  If
     <link linkend="xml.case-folding">case-folding</link> is in
     effect for this parser, the element name will be in uppercase
     letters.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is disabled.
    </para>
    <para>
     True is returned if the handlers are set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-character-data-handler">
   <refnamediv>
    <refname>xml_set_character_data_handler</refname>
    <refpurpose>set up character data handler</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_character_data_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>handler</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the character data handler function for the XML parser
     <parameter>parser</parameter>.  <parameter>handler</parameter> is
     a string containing the name of a function that must exist when
     <function>xml_parse</function> is called for
     <parameter>parser</parameter>.</para>
    <para>
     The function named by <parameter>handler</parameter> must accept
     two parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>handler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>data</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>data</parameter></term>
       <listitem>
    <simpara>
     The second parameter, <parameter>data</parameter>, contains
     the character data as a string.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist></para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is
     disabled.
    </para>
    <para>
     True is returned if the handler is set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-processing-instruction-handler">
   <refnamediv>
    <refname>xml_set_processing_instruction_handler</refname>
    <refpurpose>
     Set up processing instruction (PI) handler
    </refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_processing_instruction_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>handler</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the processing instruction (PI) handler function for the XML
     parser <parameter>parser</parameter>.
     <parameter>handler</parameter> is a string containing the name of
     a function that must exist when <function>xml_parse</function> is
     called for <parameter>parser</parameter>.
    </para>
    <para>
     A processing instruction has the following format:
     <informalexample>
      <programlisting>&lt;?
       <replaceable>target</replaceable> 
       <replaceable>data</replaceable>?>
      </programlisting>
     </informalexample>
     You can put PHP code into such a tag, but be aware of one
     limitation: in an XML PI, the PI end tag
     (<literal>?&gt;</literal>) can not be quoted, so this character
     sequence should not appear in the PHP code you embed with PIs in
     XML documents.  If it does, the rest of the PHP code, as well as
     the "real" PI end tag, will be treated as character data.
    </para>
    <para>
     The function named by <parameter>handler</parameter> must accept
     three parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>handler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>target</parameter></paramdef>
       <paramdef>string <parameter>data</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term> <listitem><simpara>
       The first parameter, <replaceable>parser</replaceable>, is a
       reference to the XML parser calling the
       handler.</simpara></listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>target</parameter></term>
       <listitem><simpara>
     The second parameter, <parameter>target</parameter>, contains
     the PI target.</simpara></listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>data</parameter></term>
       <listitem><simpara>
     The third parameter, <parameter>data</parameter>, contains
     the PI data.</simpara></listitem>
      </varlistentry>
     </variablelist></para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is disabled.
    </para>
    <para>
     True is returned if the handler is set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-default-handler">
   <refnamediv>
    <refname>xml_set_default_handler</refname>
    <refpurpose>set up default handler</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_default_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>handler</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the default handler function for the XML parser
     <parameter>parser</parameter>.  <parameter>handler</parameter> is
     a string containing the name of a function that must exist when
     <function>xml_parse</function> is called for
     <parameter>parser</parameter>.</para>
    <para>
     The function named by <parameter>handler</parameter> must accept
     two parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>handler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>data</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term>
    <parameter>parser</parameter>
       </term> 
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the
     handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term>
    <parameter>data</parameter>
       </term>
       <listitem>
    <simpara>
     The second parameter, <parameter>data</parameter>, contains
     the character data.  This may be the XML declaration,
     document type declaration, entities or other data for which
     no other handler exists.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is disabled.
    </para>
    <para>
     True is returned if the handler is set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-unparsed-entity-decl-handler">
   <refnamediv>
    <refname>xml_set_unparsed_entity_decl_handler</refname>
    <refpurpose>
     Set up unparsed entity declaration handler
    </refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_unparsed_entity_decl_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>handler</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the unparsed entity declaration handler function for the XML
     parser <parameter>parser</parameter>.
     <parameter>handler</parameter> is a string containing the name of
     a function that must exist when <function>xml_parse</function> is
     called for <parameter>parser</parameter>.</para>
    <para>
     This handler will be called if the XML parser encounters an
     external entity declaration with an NDATA declaration, like the
     following:
     <programlisting role="xml">
&lt;!ENTITY <parameter>name</parameter> {<parameter>publicId</parameter> | <parameter>systemId</parameter>} 
        NDATA <parameter>notationName</parameter>&gt;
     </programlisting>
    </para>
    <para>
     See <ulink url="&url.rec-xml;#sec-external-ent">section 4.2.2 of
     the XML 1.0 spec</ulink> for the definition of notation declared
     external entities.
    </para> 
    <para> The function named by
     <parameter>handler</parameter> must accept six parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>handler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>entityName</parameter></paramdef>
       <paramdef>string <parameter>base</parameter></paramdef>
       <paramdef>string <parameter>systemId</parameter></paramdef>
       <paramdef>string <parameter>publicId</parameter></paramdef>
       <paramdef>string <parameter>notationName</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the
     handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>entityName</parameter></term>
       <listitem>
    <simpara>
     The name of the entity that is about to be defined.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>base</parameter></term>
       <listitem><simpara>
     This is the base for resolving the system identifier
     (<parameter>systemId</parameter>) of the external
     entity.  Currently this parameter will always be set to
     an empty string.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>systemId</parameter></term>
       <listitem>
    <simpara>
     System identifier for the external entity.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>publicId</parameter></term>
       <listitem>
    <simpara> 
     Public identifier for the external entity.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>notationName</parameter></term>
       <listitem>
    <simpara> 
     Name of the notation of this entity (see
     <function>xml_set_notation_decl_handler</function>).
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist></para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is disabled.
    </para>
    <para>
     True is returned if the handler is set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-notation-decl-handler">
   <refnamediv>
    <refname>xml_set_notation_decl_handler</refname>
    <refpurpose>set up notation declaration handler</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_notation_decl_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>handler</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the notation declaration handler function for the XML parser
     <parameter>parser</parameter>.  <parameter>handler</parameter> is
     a string containing the name of a function that must exist when
     <function>xml_parse</function> is called for
     <parameter>parser</parameter>.
    </para>
    <para>
     A notation declaration is part of the document's DTD and has the
     following format: <programlisting role="xml">&lt;!NOTATION
     <parameter>name</parameter> {<parameter>systemId</parameter> |
     <parameter>publicId</parameter>}&gt;</programlisting> See <ulink
     url="&url.rec-xml;#Notations">section 4.7 of the XML 1.0
     spec</ulink> for the definition of notation declarations.
    </para>
    <para>
     The function named by <parameter>handler</parameter> must accept
     five parameters:
     <funcsynopsis>
     <funcprototype>
       <funcdef><replaceable>handler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string <parameter>notationName</parameter></paramdef>
       <paramdef>string <parameter>base</parameter></paramdef>
       <paramdef>string <parameter>systemId</parameter></paramdef>
       <paramdef>string <parameter>publicId</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term>
    <parameter>parser</parameter>
       </term> 
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the
     handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>notationName</parameter></term>
       <listitem>
    <simpara>
     This is the notation's <parameter>name</parameter>, as per
     the notation format described above.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term>
    <parameter>base</parameter>
       </term>
       <listitem>
    <simpara>
     This is the base for resolving the system identifier
     (<parameter>systemId</parameter>) of the notation
     declaration.  Currently this parameter will always be set to
     an empty string.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>systemId</parameter></term>
       <listitem>
    <simpara>
     System identifier of the external notation
     declaration.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term>
    <parameter>publicId</parameter>
       </term>
       <listitem>
    <simpara>
     Public identifier of the external notation
     declaration.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is
     disabled.
    </para>
    <para>
     True is returned if the handler is set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-set-external-entity-ref-handler">
   <refnamediv>
    <refname>xml_set_external_entity_ref_handler</refname>
    <refpurpose>set up external entity reference handler</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_set_external_entity_ref_handler</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>handler</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     Sets the notation declaration handler function for the XML parser
     <parameter>parser</parameter>.  <parameter>handler</parameter> is
     a string containing the name of a function that must exist when
     <function>xml_parse</function> is called for
     <parameter>parser</parameter>.
    </para>
    <para>
     The function named by <parameter>handler</parameter> must accept
     five parameters, and should return an integer value.  If the
     value returned from the handler is false (which it will be if no
     value is returned), the XML parser will stop parsing and
     <function>xml_get_error_code</function> will return <systemitem
     class="constant">XML_ERROR_EXTERNAL_ENTITY_HANDLING</systemitem>.
     <funcsynopsis>
     <funcprototype>
       <funcdef>int <replaceable>handler</replaceable></funcdef>
       <paramdef>int <parameter>parser</parameter></paramdef>
       <paramdef>string
        <parameter>openEntityNames</parameter>
       </paramdef>
       <paramdef>string <parameter>base</parameter></paramdef>
       <paramdef>string <parameter>systemId</parameter></paramdef>
       <paramdef>string <parameter>publicId</parameter></paramdef>
     </funcprototype>
     </funcsynopsis>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     The first parameter, <replaceable>parser</replaceable>, is a
     reference to the XML parser calling the handler.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>openEntityNames</parameter></term>
       <listitem>
    <simpara>
     The second parameter, <parameter>openEntityNames</parameter>,
     is a space-separated list of the names of the entities that
     are open for the parse of this entity (including the name of
     the referenced entity).
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>base</parameter></term>
       <listitem>
    <simpara>
     This is the base for resolving the system identifier
     (<parameter>systemid</parameter>) of the external entity.
     Currently this parameter will always be set to an empty
     string.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>systemId</parameter></term>
       <listitem>
    <simpara>
     The fourth parameter, <parameter>systemId</parameter>, is the
     system identifier as specified in the entity declaration.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>publicId</parameter></term>
       <listitem>
    <simpara>
     The fifth parameter, <parameter>publicId</parameter>, is the
     public identifier as specified in the entity declaration, or
     an empty string if none was specified; the whitespace in the
     public identifier will have been normalized as required by
     the XML spec.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     If a handler function is set to an empty string, or
     <literal>false</literal>, the handler in question is
     disabled.
    </para>
    <para>
     True is returned if the handler is set up, false if
     <parameter>parser</parameter> is not a parser.
    </para>
    <para>
     There is currently no support for object/method handlers.  See
     <function>xml_set_object</function> for using the XML parser
     within an object.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-parse">
   <refnamediv>
    <refname>xml_parse</refname>
    <refpurpose>start parsing an XML document</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int <function>xml_parse</function></funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>data</parameter></paramdef>
      <paramdef>int 
       <parameter><optional>isFinal</optional></parameter>
      </paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to use.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>data</parameter></term>
       <listitem>
    <simpara>
     Chunk of data to parse.  A document may be parsed piece-wise
     by calling <function>xml_parse</function> several times with
     new data, as long as the <parameter>isFinal</parameter>
     parameter is set and true when the last data is parsed.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>isFinal</parameter> (optional)</term>
       <listitem>
    <simpara>
     If set and true, <parameter>data</parameter> is the last
     piece of data sent in this parse.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     When the XML document is parsed, the handlers for the configured
     events are called as many times as necessary, after which this
     function returns true or false.
    </para>
    <para>
     True is returned if the parse was successful, false if it was not
     successful, or if <parameter>parser</parameter> does not refer to
     a valid parser.  For unsuccessful parses, error information can
     be retrieved with <function>xml_get_error_code</function>,
     <function>xml_error_string</function>,
     <function>xml_get_current_line_number</function>,
     <function>xml_get_current_column_number</function> and
     <function>xml_get_current_byte_index</function>.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-get-error-code">
   <refnamediv>
    <refname>xml_get_error_code</refname>
    <refpurpose>get XML parser error code</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int <function>xml_get_error_code</function></funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to get error code from.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or else it returns one of the error
     codes listed in the <link linkend="xml.error-codes">error codes
     section</link>.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-error-string">
   <refnamediv>
    <refname>xml_error_string</refname>
    <refpurpose>get XML parser error string</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>string <function>xml_error_string</function></funcdef>
      <paramdef>int <parameter>code</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>code</parameter></term>
       <listitem>
    <simpara>
     An error code from <function>xml_get_error_code</function>.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     Returns a string with a textual description of the error code
     <parameter>code</parameter>, or false if no description was found.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-get-current-line-number">
   <refnamediv>
    <refname>xml_get_current_line_number</refname>
    <refpurpose>get current line number for an XML parser</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_get_current_line_number</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to get line number from.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or else it returns which line the
     parser is currently at in its data buffer.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-get-current-column-number">
   <refnamediv>
    <refname>xml_get_current_column_number</refname> 
    <refpurpose>
     Get current column number for an XML parser
    </refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_get_current_column_number</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to get column number from.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or else it returns which column on
     the current line (as given by
     <function>xml_get_current_line_number</function>) the parser is
     currently at.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-get-current-byte-index">
   <refnamediv>
    <refname>xml_get_current_byte_index</refname>
    <refpurpose>get current byte index for an XML parser</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int 
       <function>xml_get_current_byte_index</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to get byte index from.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or else it returns which byte index
     the parser is currently at in its data buffer (starting at 0).
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-parse-into-struct">
   <refnamediv>
    <refname>xml_parse_into_struct</refname>
    <refpurpose>Parse XML data into an array structure</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int <function>xml_parse_into_struct</function></funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>string <parameter>data</parameter></paramdef>
      <paramdef>array <parameter>&amp;values</parameter></paramdef>
      <paramdef>array <parameter>&amp;index</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     This function parses an XML file into 2 parallel array
     structures, one (<parameter>index</parameter>) containing pointers 
     to the location of the appropriate values in the
     <parameter>values</parameter> array. These last two parameters
     must be passed by reference.
    </para>
    <para>
     Below is an example that illustrates the internal structure of
     the arrays being generated by the function. We use a simple
     <literal>note</literal> tag embeded inside a
     <literal>para</literal> tag, and then we parse this an print out
     the structures generated:
     <informalexample>
      <programlisting>
$simple = &quot;&lt;para&gt;&lt;note&gt;simple note&lt;/note&gt;&lt;/para&gt;&quot;;
$p = xml_parser_create();
xml_parse_into_struct($p,$simple,$vals,$index);
xml_parser_free($p);
echo "Index array\n";
print_r($index);
echo "\nVals array\n";
print_r($vals);
      </programlisting>
     </informalexample>
     When we run that code, the output will be:
     <informalexample>
      <programlisting>
Index array
Array
(
    [PARA] =&gt; Array
        (
            [0] =&gt; 0
            [1] =&gt; 2
        )

    [NOTE] =&gt; Array
        (
            [0] =&gt; 1
        )

)

Vals array
Array
(
    [0] =&gt; Array
        (
            [tag] =&gt; PARA
            [type] =&gt; open
            [level] =&gt; 1
        )

    [1] =&gt; Array
        (
            [tag] =&gt; NOTE
            [type] =&gt; complete
            [level] =&gt; 2
            [value] =&gt; simple note
        )

    [2] =&gt; Array
        (
            [tag] =&gt; PARA
            [type] =&gt; close
            [level] =&gt; 1
        )

)
      </programlisting>
     </informalexample>
    </para>
    <para>
     Event-driven parsing (based on the expat library) can get
     complicated when you have an XML document that is complex.
     This function does not produce a DOM style object, but it
     generates structures amenable of being transversed in a tree
     fashion. Thus, we can create objects representing the data
     in the XML file easily. Let's consider the following XML file
     representing a small database of aminoacids information:
     <example>
      <title>moldb.xml - small database of molecular information</title>
      <programlisting>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;moldb&gt;

    &lt;molecule&gt;
        &lt;name&gt;Alanine&lt;/name&gt;
        &lt;symbol&gt;ala&lt;/symbol&gt;
        &lt;code&gt;A&lt;/code&gt;
        &lt;type&gt;hydrophobic&lt;/type&gt;
    &lt;/molecule&gt;

    &lt;molecule&gt;
        &lt;name&gt;Lysine&lt;/name&gt;
        &lt;symbol&gt;lys&lt;/symbol&gt;
        &lt;code&gt;K&lt;/code&gt;
        &lt;type&gt;charged&lt;/type&gt;
    &lt;/molecule&gt;

&lt;/moldb&gt;
      </programlisting>
     </example>
      And some code to parse the document and generate the appropriate
      objects:
      <example>
      <title>
       parsemoldb.php - parses moldb.xml into and array of
       molecular objects
      </title>
      <programlisting role="php">
&lt;?php

class AminoAcid {
    var $name;  // aa name
    var $symbol;    // three letter symbol
    var $code;  // one letter code
    var $type;  // hydrophobic, charged or neutral
    
    function AminoAcid ($aa) {
        foreach ($aa as $k=&gt;$v)
            $this-&gt;$k = $aa[$k];
    }
}

function readDatabase($filename) {
    // read the xml database of aminoacids
    $data = implode(&quot;&quot;,file($filename));
    $parser = xml_parser_create();
    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
    xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
    xml_parse_into_struct($parser,$data,$values,$tags);
    xml_parser_free($parser);

    // loop through the structures
    foreach ($tags as $key=&gt;$val) {
        if ($key == &quot;molecule&quot;) {
            $molranges = $val;
            // each contiguous pair of array entries are the 
            // lower and upper range for each molecule definition
            for ($i=0; $i &lt; count($molranges); $i+=2) {
                    $offset = $molranges[$i] + 1;
                $len = $molranges[$i + 1] - $offset;
                $tdb[] = parseMol(array_slice($values, $offset, $len));
            }
        } else {
            continue;
        }
    }
    return $tdb;
}

function parseMol($mvalues) {
    for ($i=0; $i &lt; count($mvalues); $i++)
        $mol[$mvalues[$i][&quot;tag&quot;]] = $mvalues[$i][&quot;value&quot;];
    return new AminoAcid($mol);
}

$db = readDatabase(&quot;moldb.xml&quot;);
echo "** Database of AminoAcid objects:\n";
print_r($db);

?&gt;
      </programlisting>
      </example>
      After executing <filename>parsemoldb.php</filename>, the variable
      <varname>$db</varname> contains an array of
      <classname>AminoAcid</classname> objects, and the output of the
      script confirms that:
      <informalexample>
       <programlisting>
** Database of AminoAcid objects:
Array
(
    [0] =&gt; aminoacid Object
        (
            [name] =&gt; Alanine
            [symbol] =&gt; ala
            [code] =&gt; A
            [type] =&gt; hydrophobic
        )

    [1] =&gt; aminoacid Object
        (
            [name] =&gt; Lysine
            [symbol] =&gt; lys
            [code] =&gt; K
            [type] =&gt; charged
        )

)
       </programlisting>
      </informalexample>
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-parser-free">
   <refnamediv>
    <refname>xml_parser_free</refname>
    <refpurpose>Free an XML parser</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>string <function>xml_parser_free</function></funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to free.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist></para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or else it frees the parser and
     returns true.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-parser-set-option">
   <refnamediv>
    <refname>xml_parser_set_option</refname>
    <refpurpose>set options in an XML parser</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>int <function>xml_parser_set_option</function></funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>int <parameter>option</parameter></paramdef>
      <paramdef>mixed <parameter>value</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to set an option in.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>option</parameter></term>
       <listitem>
    <simpara>
     Which option to set.  See below.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>value</parameter></term>
       <listitem>
    <simpara>
     The option's new value.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or if the option could not be set.
     Else the option is set and true is returned.
    </para>
    <para>
     The following options are available:
     <table>
      <title>XML parser options</title>
      <tgroup cols="3">
       <thead>
    <row>
     <entry>Option constant</entry>
     <entry>Data type</entry>
     <entry>Description</entry>
    </row>
       </thead>
       <tbody>
    <row>
     <entry>XML_OPTION_CASE_FOLDING</entry>
     <entry>integer</entry>
     <entry>
      Controls whether <link
      linkend="xml.case-folding">case-folding</link> is enabled
      for this XML parser.  Enabled by default.
     </entry>
    </row>
    <row>
     <entry>XML_OPTION_TARGET_ENCODING</entry>
     <entry>string</entry> 
     <entry>
      Sets which <link linkend="xml.encoding">target
      encoding</link> to use in this XML parser.  By default, it
      is set to the same as the source encoding used by
      <function>xml_parser_create</function>.  Supported target
      encodings are <literal>ISO-8859-1</literal>,
      <literal>US-ASCII</literal> and <literal>UTF-8</literal>.
     </entry>
    </row>
       </tbody>
      </tgroup>
     </table>
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.xml-parser-get-option">
   <refnamediv>
    <refname>xml_parser_get_option</refname>
    <refpurpose>get options from an XML parser</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>mixed
       <function>xml_parser_get_option</function>
      </funcdef>
      <paramdef>int <parameter>parser</parameter></paramdef>
      <paramdef>int <parameter>option</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     <variablelist>
      <varlistentry>
       <term><parameter>parser</parameter></term>
       <listitem>
    <simpara>
     A reference to the XML parser to get an option
     from.
    </simpara>
       </listitem>
      </varlistentry>
      <varlistentry>
       <term><parameter>option</parameter></term>
       <listitem>
    <simpara>
     Which option to fetch.  See
     <function>xml_parser_set_option</function> for a list of
     options.
    </simpara>
       </listitem>
      </varlistentry>
     </variablelist>
    </para>
    <para>
     This function returns false if <parameter>parser</parameter> does
     not refer to a valid parser, or if the option could not be set.
     Else the option's value is returned.
    </para>
    <para>
     See <function>xml_parser_set_option</function> for the list of
     options.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.utf8-decode">
   <refnamediv>
    <refname>utf8_decode</refname> 
    <refpurpose>
     Converts a string with ISO-8859-1 characters encoded with UTF-8
     to single-byte ISO-8859-1.
    </refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>string <function>utf8_decode</function></funcdef>
      <paramdef>string <parameter>data</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     This function decodes <parameter>data</parameter>, assumed to be
     <literal>UTF-8</literal> encoded, to <literal>ISO-8859-1</literal>.
    </para>
    <para>
     See <function>utf8_encode</function> for an explaination of UTF-8
     encoding.
    </para>
   </refsect1>
  </refentry>

  <refentry id="function.utf8-encode">
   <refnamediv>
    <refname>utf8_encode</refname>
    <refpurpose>encodes an ISO-8859-1 string to UTF-8</refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
    <funcsynopsis>
     <funcprototype>
      <funcdef>string <function>utf8_encode</function></funcdef>
      <paramdef>string <parameter>data</parameter></paramdef>
     </funcprototype>
    </funcsynopsis>
    <para>
     This function encodes the string <parameter>data</parameter> to
     <literal>UTF-8</literal>, and returns the encoded version.
     <literal>UTF-8</literal> is a standard mechanism used by
     <acronym>Unicode</acronym>for encoding <glossterm>wide
     character</glossterm> values into a byte stream.
     <literal>UTF-8</literal> is transparent to plain
     <abbrev>ASCII</abbrev> characters, is self-synchronized (meaning
     it is possible for a program to figure out where in the
     bytestream characters start) and can be used with normal string
     comparison functions for sorting and such.  PHP encodes
     <literal>UTF-8</literal> characters in up to four bytes, like
     this:
     <table>
      <title>UTF-8 encoding</title>
      <tgroup cols="3">
       <thead>
    <row>
     <entry>bytes</entry>
     <entry>bits</entry>
     <entry>representation</entry>
    </row>
       </thead>
       <tbody>
    <row>
     <entry>1</entry>
     <entry>7</entry>
     <entry>0bbbbbbb</entry>
    </row>
    <row>
     <entry>2</entry>
     <entry>11</entry>
     <entry>110bbbbb 10bbbbbb</entry>
    </row>
    <row>
     <entry>3</entry>
     <entry>16</entry>
     <entry>1110bbbb 10bbbbbb 10bbbbbb</entry>
    </row>
    <row>
     <entry>4</entry>
     <entry>21</entry>
     <entry>11110bbb 10bbbbbb 10bbbbbb 10bbbbbb</entry>
    </row>
       </tbody>
      </tgroup>
     </table>
     Each <replaceable>b</replaceable> represents a bit that can be
     used to store character data.
    </para>
   </refsect1>
  </refentry>

 </reference>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->