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