Sommaire
Analyseur syntaxique XML
Introduction
Quelques exemples
xml_parser_create
xml_set_object
xml_set_element_handler
xml_set_character_data_handler
xml_set_processing_instruction_handler
xml_set_default_handler
xml_set_unparsed_entity_decl_handler
xml_set_notation_decl_handler
xml_set_external_entity_ref_handler
xml_parse
xml_get_error_code
xml_error_string
xml_get_current_line_number
xml_get_current_column_number
xml_get_current_byte_index
xml_parse_into_struct
xml_parser_free
xml_parser_set_option
xml_parser_get_option
utf8_decode
utf8_encode
|
6.102.2 Quelques exemples
Voici une liste d'exemple de code PHP qui analyse un document XML.
6.102.2.1 Exemple de structure XML
Ce premier exemple affiche la structure de l'élément
de début dans un document avec indentation.
Afficher une structure XML |
<?php $file = "data.xml"; $depth = array(); function startElement($parser, $name, $attrs) { global $depth; for ($i = 0; $i < $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); ?>
|
6.102.2.2 XML Transtypage XML -> HTML
XML Transtypage XML -> HTML |
Cet exemple remplace les balises XML d'un document par des balises
HTML. Les éléments inconnus seront ignorés.
Bien entendu, cet exemple sera appliqué à un type
précis de fichiers XML.
<?php $file = "data.xml"; $map_array = array( "BOLD" => "B", "EMPHASIS" => "I", "LITERAL" => "TT" ); function startElement($parser, $name, $attrs) { global $map_array; if ($htmltag = $map_array[$name]) { print "<$htmltag>"; } } function endElement($parser, $name) { global $map_array; if ($htmltag = $map_array[$name]) { print "</$htmltag>"; } } 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); ?>
|
6.102.2.3 XML Entité externe
Cet exemple exploite les références externes de XML :
il est possible d'utiliser un gestionnaire d'entité externe
pour inclure et analyser les documents, tous comme les instructions
exécutables peuvent servir à inclure et analyser
d'autres documents, et aussi fournir une indication de confiance
(voir plus bas).
Le document XML qui est utilisé dans cet exemple est fourni plus
loin dans l'exemple (xmltest.xml
et
xmltest2.xml
).
Entité externe |
<?php $file = "xmltest.xml"; function trustedFile($file) { // only trust local files owned by ourselves if (!eregi("^([a-z]+)://", $file) && fileowner($file) == getmyuid()) { return TRUE; } return FALSE; } function startElement($parser, $name, $attribs) { print "<<font color=\"#0000cc\">$name</font>"; if (sizeof($attribs)) { while (list($k, $v) = each($attribs)) { print " <font color=\"#009900\">$k</font>=\"<font color=\"#990000\">$v</font>\""; } } print ">"; } function endElement($parser, $name) { print "</<font color=\"#0000cc\">$name</font>>"; } function characterData($parser, $data) { print "<B>$data</B>"; } 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("Code PHP peu sûr : <B>%s</B>", htmlspecialchars($data)); } break; } } function defaultHandler($parser, $data) { if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { printf('<font color="#aa00aa">%s</font>', htmlspecialchars($data)); } else { printf('<font size="-1">%s</font>', 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 "<pre>"; 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 "</pre>"; print "parse complete\n"; xml_parser_free($xml_parser); ?>
|
xmltest.xml |
<?xml version='1.0'?> ]]> <!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [ <!ENTITY plainEntity "FOO entity"> <!ENTITY systemEntity SYSTEM "xmltest2.xml"> ]> <chapter> <TITLE>Title &plainEntity;</TITLE> <para> <informaltable> <tgroup cols="3"> <tbody> <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row> <row><entry>a2</entry><entry>c2</entry></row> <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row> </tbody> </tgroup> </informaltable> </para> &systemEntity; <sect1 id="about"> <title>About this Document</title> <para> <!-- this is a comment --> <?php print 'Hi! This is PHP version '.phpversion(); ?> ]]> </para> </sect1> </chapter>
|
Ce fichier est inclus depuis xmltest.xml
:
xmltest2.xml |
<?xml version="1.0" ?> ]]> <!DOCTYPE foo [ <!ENTITY testEnt "test entity"> ?> ]]> <foo> <element attrib="value"?> ]]> &testEnt; <?php print "This is some more PHP code being executed."; ?> ]]> </foo>
|
|