XML értelmező függvények
Bevezetés
Az XML (eXtensible Markup Language) olyan adatformátum, amit a Weben keresztüli adatcserére terveztek. Ezt az ajánlást a World Wide Web Consortium (W3C) dolgozta ki és gondozza. További információk az XML-rÅ‘l és a kapcsolódó technológiákról a » https://www.w3.org/XML/ cÃmen található.
Ez a kiterjesztés James Clark expat könyvtárát használja, amely a » https://www.jclark.com/xml/expat.html cÃmen beszerezhetÅ‘. Ez lehetÅ‘ teszi XML dokumentumok beolvasását, ún. elemzését, de nemazok érvényesÃtését. Három különbözÅ‘ PHP által is támogatott forrás-karakterkódolást támogat: US-ASCII, ISO-8859-1 és UTF-8. UTF-16 nincs támogatva.
Ez a kiterjesztés lehetÅ‘séget nyújt arra, hogy XML elemzÅ‘ket hozzunk létre és azokhoz saját kezelÅ‘függvényeket rendeljünk hozzá, amelyek más és más események esetén futnak le. Minden XML elemzÅ‘nek néhány paramétere beállÃtható, ami a működését befolyásolja.
Követelmények
Ez a kiterjesztés az expat könyvtárat használja, amely a » https://www.jclark.com/xml/expat.html cÃmen beszerezhetÅ‘. A Makefile, amely ezzel a csomaggal jön alapértelmezés szerint nem telepÃti a nekünk szükséges eljáráskönyvtárat, ehhez a következÅ‘ sorokat kell beleÃrni:
libexpat.a: $(OBJS) ar -rc $@ $(OBJS) ranlib $@
TelepÃtés
Az Apache 1.3.7 vagy késÅ‘bbi verziójával már együtt jár az expat könyvtár. Ekkor a PHP-t csak egyszerűen a --with-xml opcióval kell fordÃtani - minden kiegészÃtÅ‘ elérési útvonal nélkül - és ekkor az Apacheüba épÃtett expat könyvtárat használja majd.
Az UNIX rendszereken a configure parancsot kell a --with-xml kapcsolóval. Az expat könyvtárnak olyan helyen kell installálva lennie, ahol a fordÃtó el tudja érni. Ha a PHP-t modulként Apache 1.3.9 (ennek vagy késÅ‘bbi verziójú) alá installálod, akkor a PHP automatikusan az Apache beépÃtett expat eljáráskönyvtárat fogja használni. Szükség lehet CPPFLAGS és a LDFLAGS környezeti változók beállÃtására a rendszeren, mielÅ‘tt elindÃtod a configure parancsot, ha az expat-ot valamilyen egzotikus helyre installálták.
A PHP telepÃtése.... Tada! Ezt kell(ene) látnod!
Futásidejű beállÃtások
Ez a kiterjesztés semmilyen konfigurációs beállÃtásokat nem definiál a php.ini állományban.
ErÅ‘forrás tÃpusok
Ez a kiterjesztés semmilyen erÅ‘forrás tÃpust nem definiál.
Előre definiált állandók
Az itt listázott állandókat ez a kiterjesztés definiálja, és csak akkor elérhetÅ‘ek, ha az adott kiterjesztés be van fordÃtva a PHP-be, vagy dinamikusan betöltött.
- XML_ERROR_NONE (integer)
- XML_ERROR_NO_MEMORY (integer)
- XML_ERROR_SYNTAX (integer)
- XML_ERROR_NO_ELEMENTS (integer)
- XML_ERROR_INVALID_TOKEN (integer)
- XML_ERROR_UNCLOSED_TOKEN (integer)
- XML_ERROR_PARTIAL_CHAR (integer)
- XML_ERROR_TAG_MISMATCH (integer)
- XML_ERROR_DUPLICATE_ATTRIBUTE (integer)
- XML_ERROR_JUNK_AFTER_DOC_ELEMENT (integer)
- XML_ERROR_PARAM_ENTITY_REF (integer)
- XML_ERROR_UNDEFINED_ENTITY (integer)
- XML_ERROR_RECURSIVE_ENTITY_REF (integer)
- XML_ERROR_ASYNC_ENTITY (integer)
- XML_ERROR_BAD_CHAR_REF (integer)
- XML_ERROR_BINARY_ENTITY_REF (integer)
- XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF (integer)
- XML_ERROR_MISPLACED_XML_PI (integer)
- XML_ERROR_UNKNOWN_ENCODING (integer)
- XML_ERROR_INCORRECT_ENCODING (integer)
- XML_ERROR_UNCLOSED_CDATA_SECTION (integer)
- XML_ERROR_EXTERNAL_ENTITY_HANDLING (integer)
- XML_OPTION_CASE_FOLDING (integer)
- XML_OPTION_TARGET_ENCODING (integer)
- XML_OPTION_SKIP_TAGSTART (integer)
- XML_OPTION_SKIP_WHITE (integer)
Eseménykezelők
A definiálható XML eseménykezelők:
PHP függvány ,amely regisztrálja a kezelÅ‘t | esemény leÃrása |
---|---|
xml_set_element_handler() | Elem esemény akkor történik, amikor az XML elemzÅ‘ egy elem kezdÅ‘ vagy zárócÃmkéjével találkozik. A nyÃtó és zárócÃmkékhez külön eseménykezelÅ‘k rendelhetÅ‘k. |
xml_set_character_data_handler() | (Elemzett) szöveges adatnak tekinthető durván minden, ami az XML dokumentumban nem a jelölésekhez tartozó tartalom, beleértve a jelölések közti térközöket is. Az XML elemző nem ad és nem vesz el semmilyen térkökaraktert az elemzés során a dokumentumból, ez teljes mértékben a feldolgozó alkalmazás feladata, illetve annak eldöntése, hogy ezek a karakterek értékes információt jelentenek vagy sem. |
xml_set_processing_instruction_handler() | PHP programozók számára ismerÅ‘s lehet a feldolgozó utasÃtás (proccesing instructions: PI) fogalma. A <?php ?> maga is ilyen, ahol a php a feldolgozó utasÃtás "célpontja", magyarán a megcélzott feldolgozó. Ezek mind az alkalmazásfüggÅ‘ elemek, kivéve az XML jelölésűeket, amely lefoglalt ebben az esetben is. |
xml_set_default_handler() | Azok az adatok, amelyek semmilyen más kezelÅ‘ nem kezel le, ehhez a függvényhez kerülnek, pl.: XML és dokumentumtÃpus deklaráció. |
xml_set_unparsed_entity_decl_handler() | Ezt a kezelÅ‘t hÃvja meg az elemzÅ‘, ha jelölés deklarációs egyedet (unparsed, NDATA entity). kell feldolgozni. |
xml_set_notation_decl_handler() | Ez a kezelő felelős a jelölések deklarációjáért. |
xml_set_external_entity_ref_handler() | Ezt az kezelÅ‘t hÃvja meg az elemzÅ‘, ha egy külsÅ‘ egyedhivatkozást talál. Ez lehet állományra vagy URL-re történÅ‘ hivatkozás. Lásd a Példák külsÅ‘ egyedek kezelésére c. fejezetet! |
Betű egységesÃtés (case-folding)
Az elemek nevei kisbetűket és nagybetűket vegyesen tartalmazhatnak. Az elemkezelő fügvények szempontjából ez nem mindegy, ezért az XML szabvány definiált egy betűkezelő szabályt, mely szerint "ha kisbetűt, nagybetűt vegyesen tartalmazó karaktersorozatot kell feldolgozni, akkor a karaktersorozatban a kisbetűket ki kell cserélni a nekik megfelelő nagybetűkre". Más szavakkal, amikor egy karaktersorozat érkezik az XML értelmezőhöz, a betűkezelés egyszerűen a teljes nagybetűre váltást jelenti.
Alapértelmezés szerint az XML kezelÅ‘k már nagybetűre váltott formában kapják meg a neveket az értelmezÅ‘tÅ‘l. Ez a viselkedés azonban lekérdezhetÅ‘ ill. megváltoztatható az XML elemzÅ‘ következÅ‘ két függvényével: xml_parser_get_option() (lekérdezés) és a xml_parser_set_option() (beállÃtás) függvényekkel.
Hibaüzenetek
A következő hibaüzeneteket definálták (az xml_parse() függvény visszatérési értékei lehetnek):
- XML_ERROR_NONE
- XML_ERROR_NO_MEMORY
- XML_ERROR_SYNTAX
- XML_ERROR_NO_ELEMENTS
- XML_ERROR_INVALID_TOKEN
- XML_ERROR_UNCLOSED_TOKEN
- XML_ERROR_PARTIAL_CHAR
- XML_ERROR_TAG_MISMATCH
- XML_ERROR_DUPLICATE_ATTRIBUTE
- XML_ERROR_JUNK_AFTER_DOC_ELEMENT
- XML_ERROR_PARAM_ENTITY_REF
- XML_ERROR_UNDEFINED_ENTITY
- XML_ERROR_RECURSIVE_ENTITY_REF
- XML_ERROR_ASYNC_ENTITY
- XML_ERROR_BAD_CHAR_REF
- XML_ERROR_BINARY_ENTITY_REF
- XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
- XML_ERROR_MISPLACED_XML_PI
- XML_ERROR_UNKNOWN_ENCODING
- XML_ERROR_INCORRECT_ENCODING
- XML_ERROR_UNCLOSED_CDATA_SECTION
- XML_ERROR_EXTERNAL_ENTITY_HANDLING
Karakterkódolások
A PHP XML kiterjesztése támogatja az » Unicode karakterkészeletet különbözÅ‘ karakterkódolások által. Kétféle karakterkódolás különböztetünk meg, az ún. forrás kódolást és a cél kódolást. A PHP belsÅ‘, értelmezési célokra a dokumentumokat mindig UTF-8 karakterkódolás szerint kódolja.
A forrás-kódolás az XML dokumentum értelmezése, elemzése során használja. Az XML értelmezőt létrehozásakor meg lehet határozni az elemző forrás kódolását, amit később már nem lehet megváltoztatni. A támogatott karakterkészletek a forrás kódolás számára a következők: ISO-8859-1, US-ASCII és az UTF-8. Az első kettő egybájtos kódolás, ami annyit tesz, hogy minden karaktert egyetlen bájton ábrázolnak. Az UTF-8 egy és négy bájt között különböző hosszúságú bitláncon (21 hosszúig) tudja ábrázolja a karaktereket. A forrás kódolás alapértelmezett karakterkészlete a PHP-ben a ISO-8859-1.
A cél-kódolás akkor készül el, amikor a PHP átadja az adatokat az XML kezelÅ‘ függvényeknek. Amikor egy XML elemzÅ‘ létrejön, a cél-kódolás a forrás-kódolásához igazodik, de ezt meg lehet változtatni a késÅ‘bbiek során. A cél-kódolás hatással lesz a karakteres adatra, XML elemek cÃmkéire és a feldolgozó utasÃtásokban definiált célpontokra is!
Ha az XML elemző olyan karaktert talál, mely nincs definiálva a forrás-kódolás karakterkészletében, akkor ez hibát okoz.
Ha az értelmezett XML dokumentumban találkozik a PHP egy olyan karakterrel, amit nem nem tud megjelenÃteni a cél-kódolás karakterkészlete, akkor a problémás karaktert "lefokozza". Ez annyit jelent, hogy kérdÅ‘jelet rak a helyébe.
Példák
Here are some example PHP scripts parsing XML documents.
XML Element Structure Example
This first example displays the stucture of the start elements in a document with indentation.
Example#1 Show XML Element Structure
<?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);
XML External Entity Example
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.
XML documents that can be used for this example are found below the example (xmltest.xml and xmltest2.xml.)
Example#3 External Entity Example
$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("Untrusted PHP code: <i>%s</i>",
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);
?>
Example#4 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; <section xml:id="about"> <title>About this Document</title> <para> <!-- this is a comment --> <?php print 'Hi! This is PHP version '.phpversion(); ?> </para> </section> </chapter>
This file is included from xmltest.xml:
Example#5 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>
Table of Contents
- utf8_decode — UTF-8 kódolt sztring ISO-8859-1 karaktereit egybájtos ISO-8859-1 karakterekre cseréli
- utf8_encode — ISO-8859-1 szöveget UTF-8 szerint kódol át
- xml_error_string — Kinyeri XML elemző által meghatározott hibaszöveget
- xml_get_current_byte_index — Visszaadja az XML elemző aktuális bájtindexét
- xml_get_current_column_number — visszaadja az XML elemző aktuális oszlop számát
- xml_get_current_line_number — Visszaadja az XML elemző aktuális sorindexét
- xml_get_error_code — Visszadja az elemzés hibakódját
- xml_parse_into_struct — XML adatot tömbökbe pakol
- xml_parse — Elemez egy XML dokumentumot
- xml_parser_create_ns — XML elemzőt hoz létre
- xml_parser_create — XML elemzőt hoz létre
- xml_parser_free — megszünteti az XML elemzőt
- xml_parser_get_option — információt ad az XML elemzőről
- xml_parser_set_option — beállÃtja az XML elemzÅ‘ paramétereit
- xml_set_character_data_handler — Szövegkezelő függvényt rendel az elemzőhöz
- xml_set_default_handler — Alap sztringkezelő függvényt rendel az elemzőhöz
- xml_set_element_handler — Nyitó és záró jelöléseket kezelő függvényt rendel az elemzőhöz
- xml_set_end_namespace_decl_handler — Névtér végének deklarációját végző kezelőgüggvény megadása
- xml_set_external_entity_ref_handler — Külső egyedek kezelésére rendel függvényt az elemzőhöz
- xml_set_notation_decl_handler — jelölések kezelésére rendel függvényt az elemzőhöz
- xml_set_object — objektumon belüli XML elemző használatához
- xml_set_processing_instruction_handler — PI kezelőt rendel az elemzőhöz
- xml_set_start_namespace_decl_handler — Névtér kezdetének deklarációját végző kezelőfüggvény megadása
- xml_set_unparsed_entity_decl_handler — "nem elemzendÅ‘ egyedek" kezelÅ‘függvényét állÃtja be az elemzÅ‘ számára