<?xml version="1.0" encoding="iso-8859-1"?> <!-- $Revision$ --> <refentry xmlns="http://docbook.org/ns/docbook" xml:id="function.xml-parse-into-struct"> <refnamediv> <refname>xml_parse_into_struct</refname> <refpurpose>Parse XML data into an array structure</refpurpose> </refnamediv> <refsect1 role="description"> &reftitle.description; <methodsynopsis> <type>int</type><methodname>xml_parse_into_struct</methodname> <methodparam><type>resource</type><parameter>parser</parameter></methodparam> <methodparam><type>string</type><parameter>data</parameter></methodparam> <methodparam><type>array</type><parameter role="reference">values</parameter></methodparam> <methodparam choice="opt"><type>array</type><parameter role="reference">index</parameter></methodparam> </methodsynopsis> <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> </refsect1> <refsect1 role="parameters"> &reftitle.parameters; <para> <variablelist> <varlistentry> <term><parameter>parser</parameter></term> <listitem> <para> </para> </listitem> </varlistentry> <varlistentry> <term><parameter>data</parameter></term> <listitem> <para> </para> </listitem> </varlistentry> <varlistentry> <term><parameter>values</parameter></term> <listitem> <para> </para> </listitem> </varlistentry> <varlistentry> <term><parameter>index</parameter></term> <listitem> <para> </para> </listitem> </varlistentry> </variablelist> </para> </refsect1> <refsect1 role="returnvalues"> &reftitle.returnvalues; <para> <function>xml_parse_into_struct</function> returns 0 for failure and 1 for success. This is not the same as &false; and &true;, be careful with operators such as ===. </para> </refsect1> <refsect1 role="examples"> &reftitle.examples; <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 embedded inside a <literal>para</literal> tag, and then we parse this and print out the structures generated: <example> <title><function>xml_parse_into_struct</function> example</title> <programlisting role="php"> <![CDATA[ <?php $simple = "<para><note>simple note</note></para>"; $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> <para> When we run that code, the output will be: </para> <screen> <![CDATA[ Index array Array ( [PARA] => Array ( [0] => 0 [1] => 2 ) [NOTE] => Array ( [0] => 1 ) ) Vals array Array ( [0] => Array ( [tag] => PARA [type] => open [level] => 1 ) [1] => Array ( [tag] => NOTE [type] => complete [level] => 2 [value] => simple note ) [2] => Array ( [tag] => PARA [type] => close [level] => 1 ) ) ]]> </screen> </example> </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 role="xml"> <![CDATA[ <?xml version="1.0"?> <moldb> <molecule> <name>Alanine</name> <symbol>ala</symbol> <code>A</code> <type>hydrophobic</type> </molecule> <molecule> <name>Lysine</name> <symbol>lys</symbol> <code>K</code> <type>charged</type> </molecule> </moldb> ]]> </programlisting> </example> And some code to parse the document and generate the appropriate objects: <example> <title> parsemoldb.php - parses moldb.xml into an array of molecular objects </title> <programlisting role="php"> <![CDATA[ <?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=>$v) $this->$k = $aa[$k]; } } function readDatabase($filename) { // read the XML database of aminoacids $data = implode("", 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=>$val) { if ($key == "molecule") { $molranges = $val; // each contiguous pair of array entries are the // lower and upper range for each molecule definition for ($i=0; $i < 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 < count($mvalues); $i++) { $mol[$mvalues[$i]["tag"]] = $mvalues[$i]["value"]; } return new AminoAcid($mol); } $db = readDatabase("moldb.xml"); echo "** Database of AminoAcid objects:\n"; print_r($db); ?> ]]> </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> <screen> <![CDATA[ ** Database of AminoAcid objects: Array ( [0] => aminoacid Object ( [name] => Alanine [symbol] => ala [code] => A [type] => hydrophobic ) [1] => aminoacid Object ( [name] => Lysine [symbol] => lys [code] => K [type] => charged ) ) ]]> </screen> </informalexample> </para> </refsect1> </refentry> <!-- 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 indent-tabs-mode:nil sgml-parent-document:nil sgml-default-dtd-file:"~/.phpdoc/manual.ced" sgml-exposed-tags:nil sgml-local-catalogs:nil sgml-local-ecat-files:nil End: vim600: syn=xml fen fdm=syntax fdl=2 si vim: et tw=78 syn=sgml vi: ts=1 sw=1 -->