XML parser συναρτήσεις
Εισαγωγή
Η XML (eXtensible Markup Language) είναι μια μορφή δεδομένων για ανταλλαγή δομημένων αρχείων στο Web. Είναι ένα standard καθορισμένο από το The World Wide Web consortium (W3C). Πληροφορίες σχετικά με την XML και τις συσχετιζόμενες μ'αυτήν τεχνολογίες μπορείτε να βρείτε στο » https://www.w3.org/XML/.
Αυτή η επέκταση της PHP υλοποιεί υποστήριξη για την expat του James Clark στην PHP. Αυτό το εργαλείο σας επιτρέπεται να μεταγλωτίσετε, αλλά όχι να ελένξετε την εγκυρότητα, των XML αρχείων. Υποστηρίζει τρία πηγές κωδικοποίησης χαρακτήρων που παρέχονται επίσης και από την by PHP: την US-ASCII, την ISO-8859-1 και την UTF-8. Η UTF-16 δεν υποστηρίζεται.
Αυτή η επέκταση σας επιτρέπει να δημιουργήσετε XML parsers και στη συνέχεια να ορίσετε handlers για διαφορετικά XML events. Ο κάθε XML parser έχει επίσης και μερικές παραμέτρους τις οποίες μπορείτε να ρυθμίσετε.
Απαιτήσεις
Αυτή η επέκταση χρησιμοποιεί την expat, η οποία μπορεί να βρεθεί στο » https://www.jclark.com/xml/expat.html. Η Makefile που συνοδεύει την expat δεν δημιουργεί μια library εκ των πραγμάτων, μπορείτε να χρησιμοποιήσετε αυτό για να δημιουργήσετε έναν κανόνα για εκείνο:
libexpat.a: $(OBJS) ar -rc $@ $(OBJS) ranlib $@
Εγκατάσταση
Αυτές οι συναρτήσεις είναι ενεργοποιημένες by default, χρησιμοποιώντας την bundled expat library. Μπορείτε να απενεργοποιήσετε την υποστήριξη της XML με την --disable-xml. Αν κάνετε compile την PHP ως module για τον Apache 1.3.9 και μετά, η PHP θα χρησιμοποιήσει αυτόματα την bundled expat library από τον Apache. Σε περίπτωση που δε θέλετε να χρησιμοποιήσετε την bundled expat library ρυθμίστε την PHP --with-expat-dir=DIR, όπου η DIR θα πρέπει να δείχνει στο βασικό κατάλογο εγκατάστασης του expat.
Η έκδοση για windows της PHP έχει ενσωματωμένη υποστήριξη για αυτή την επέκταση. Δεν χρειάζεται να φορτώσετε κάποια πρόσθετη επέκταση για να χρησιμοποιήσετε αυτές τις συναρτήσεις.
Ρυθμίσεις κατά την εκτέλεση
Αυτή η επέκταση δεν έχει directives ρύθμισης ορισμένα στο php.ini.
Τύποι Πόρων
xml
Η xml resource όπως επιστρέφεται από την xml_parser_create() και την xml_parser_create_ns() κάνει αναφορά σε ένα στιγμιότυπο του xml parser για να χρησιμοποιηθεί με τις συναρτήσεις που παρέχονται από αυτή την επέκταση.
Προκαθορισμένες Σταθερές
Οι σταθερές παρακάτω ορίζονται από αυτή την επέκταση, και θα είναι διαθέσιμες μόνο αν η επέκταση έχει γίνει compile μέσα στην PHP ή έχει φορτωθεί δυναμικά κατά την εκτέλεση.
- 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)
Event Handlers
Οι event handlers (χειριστές γεγονότων) της XML που έχουν οριστεί είναι:
Συνάρτηση της PHP που ορίζει τον handler | Περιγραφή Event |
---|---|
xml_set_element_handler() | Τα events ενός στοιχείου ενεργοποιούνται όταν ο XML parser συναντά tags αρχής ή τέλους. Υπάρχουν ξεχωριστοί handlers για tags αρχής και tags τέλους. |
xml_set_character_data_handler() | Τα δεδομένα χαρακτήρων είναι σχεδόν όλα τα περιεχόμενα των XML αρχείων που δεν είναι markup, συμπεριλαμβανομένου των κενών ανάμεσα στα tags. Σημειώστε ότι ο XML parser δεν προσθέτει ή αφαιρεί κάποιο κενό, εξαρτάται από την εφαρμογή σας (από εσάς) να αποφασισθεί αν τα κενά είναι σημαντικά. |
xml_set_processing_instruction_handler() | Οι προγραμματιστές σε PHP έχουν οικειότητα με εντολές διαδικασιών (processing instructions - PIs). Η <?php ?> είναι μια processing instruction, όπου η php καλείται "PI target". Ο χειρισμός αυτών καθορίζεται από τις εφαρμογές, εκτός από το οτι όλοι οι PI targets που αρχίζουν με "XML" είναι δεσμευμένοι. |
xml_set_default_handler() | Ό,τι δεν πάει σε κάποιο άλλο handler πηγαίνει στον προκαθορισμένο handler. Θα πάρετε πράγματα όπως η XML και η δήλωση τύπων του αρχείου στο προκαθορισμένο handler. |
xml_set_unparsed_entity_decl_handler() | Αυτός ο handler θα καλείται για δήλωση μια οντότητας (NDATA) στην οποία δεν έχει γίνει parse. |
xml_set_notation_decl_handler() | Αυτός ο handler καλείται για δήλωση μια σημείωσης (notation). |
xml_set_external_entity_ref_handler() | Αυτός ο handler καλείται όταν ο XML parser βρίσκει μια αναφορά σε μια εξωτερικά μεταγλωττισμένη γενική οντότητα. Αυτό μπορεί να είναι ναναφορά σε ένα αρχείο ή σε ένα URL, για παράδειγμα. Δείτε το παράδειγμα για εξωτερικές οντότητες για μια επίδειξη. |
Case Folding
Οι συναρτήσεις που χειρίζονται ένα στοιχείο μπορούν να πάρουν τα element ονόματα τους ως case-folded. Το Case-folding ορίζεται από το standard της XML ως "η διαδικασία που εφαρμόζεται σε μια ακολουθία χαρακτήρων, στην οποία αυτοί οι identified ως μη-κεφαλαίοι αντικαθίστανται από τους αντίστοιχους τους κεφαλαίους". Με άλλα λόγια, όταν ερχόμαστε στην XML, το case-folding σημαίνει απλά μετατροπή σε κεφαλαία.
Είναι προκαθορισμένο ότι όλα τα ονόματα των στοιχείων που περνούν σε συναρτήσεις handler είναι case-folded. Αυτή η συμπεριφορά μπορεί να ερωτηθεί και να ελενχθεί ανά XML parser με τις συναρτήσεις xml_parser_get_option() και xml_parser_set_option() , αντίστοιχα.
Κωδικοί Λάθους (Error Codes)
Οι ακόλουθες σταθερές έχουν οριστεί για κωδικούς λάθους της XML (όπως επιστρέφονται από την xml_parse()):
- 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
Κωδικοποίηση Χαρακτήρων
Η επέκταση σε XML της PHP υποστηρίζει το σύνολο χαρακτήρων » Unicode διαμέσου διαφορετικών κωδικοποιήσεων χαρακτήρων. Υπάρχουν δύο τύποι κωδικοποίησης χαρακτήρων, η source κωδικοποίηση και η target κωδικοποίηση. η εσωτερική αναπαράσταση της PHP ενός αρχείου είναι πάντα κωδικοποιημένη με UTF-8.
Η Source κωδικοποίηση γίνεται όταν ένα XML αρχείο μεταγλωττίζεται. Όταν δημιουργείται ένας XML parser, η source κωδικοποίηση μπορεί να προσδιοριστεί (αυτή η κωδικοποίηση δεν μπορεί να αλλάξει αργότερα στο χρόνο ζωής του XML parser). Οι source κωδικοποιήσεις που υποστηρίζονται είναι η ISO-8859-1, η US-ASCII και η UTF-8. Οι δυο πρώτες είναι single-byte κωδικοποιήσεις, το οποίο σημαίνει ότι κάθε χαρακτήρας αναπαρίσταται από ένα μόνο byte. Η UTF-8 μπορεί να κωδικοποιήσει χαρακτήρες που αποτελούνται από έναν μεταβλητό αριθμό από bits (μέχρι 21) από ένα μέχρι τέσσετα bytes. Η προκαθορισμένη source κωδικοποίηση που χρησιμοποιείται στην PHP είναι η ISO-8859-1.
Η Target κωδικοποίηση γίνεται όταν η PHP μεταφέρει δεδομένα σε XML handler συναρτήσεις. Όταν ένας XML parser δημιουργείται, η target κωδικοποίηση ορίζεται ίδια με την source κωδικοποίηση, αλλά αυτό μπορεί να αλλάξει σε οποιοδήποτε σημείο. Η target κωδικοποίηση θα επηρεάσει τα δεδομένα των χαρακτήρων καθώς επίσης και τα ονόματα των tags και τα processing instruction targets.
Αν ο XML parser συναντήσει χαρακτήρες εκτός πεδίου που η source κωδικοποίηση μπορεί να αναπαραστήσει, θα επιστρέψει ένα λάθος.
Αν η PHP συνατήσει χαρακτήρες στο μεταγλωττισμένο XML αρχείο που δεν μπορεί να αναπαραστήσει στην επιλεγμένη target κωδικοποίηση, οι προβληματικοί χαρακτήρες θα "υποβιβαστούν". Προσ το παρόν, αυτό σημαίνει ότι τέτοιοι χαρακτήρες αντικαθίστανται από το αγγλικό ερωτηματικό.
Παραδείγματα
Εδώ υπάρχουν μερικά ενδεικτικά PHP scripts που κάνουν μεταγλώττιση σε XML αρχεία.
Παράδειγμα δομής στοιχείου (element) XML
Το πρώτο παράδειγμα εμφανίζει τη δομή των αρχικών elements σε ένα αρχείο με εσοχές.
Example#1 Εμφάνιση της δομής ενός XML Element
<?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
Αυτό το παράδειγμα αντικατοπτρίζει τον XML κώδικα. Δείχνει πως να χρησιμοποιήσετε έναν external entity reference handler για να συμπεριλάβετε και να κάνετε parse και σε άλλα αρχεία, καθώς επίσης και πώς οι PIs μπορούν να εκτελεστούν, και έναν τρόπο για να καθοριστούν οι "έμπιστοι" PIs που περιέχουν κώδικα.
Τα XML αρχεία που μπορούν να χρησιμοποιηθούν σ'αυτό το παράδειγμα βρίσκονται κάτω από το παράδειγμα (xmltest.xml και xmltest2.xml.)
Example#3 Πάραδειγμα για External Entity
<?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("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>Σχετικά με αυτό το αρχείο</title> <para> <!-- this is a comment --> <?php print 'Hi! This is PHP version '.phpversion(); ?> </para> </section> </chapter>
Αυτό το αρχείο συμπεριλαμβάνεται από το 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 — Μετατρέπει ένα string με ISO-8859-1 χαρακτήρες κωδικοποιημένο με UTF-8 σε single-byte ISO-8859-1.
- utf8_encode — Κωδικοποιεί ένα ISO-8859-1 string σε UTF-8
- xml_error_string — Παίρνει το error string του XML parser
- xml_get_current_byte_index — Παίρνει το τρέχον byte index για έναν XML parser
- xml_get_current_column_number — Παίρνει τον τρέχον αριθμό της στήλης για έναν XML parser
- xml_get_current_line_number — παίρνει στον τρέχον αριθμό γραμμή για έναν XML parser
- xml_get_error_code — παίρνει τον XML parser error code
- xml_parse_into_struct — Μεταγλωτίζει τα XML δεδομένα σε μια δομή πίνακα
- xml_parse — αρχίζει να μεταγλωτίζει ένα XML αρχείο
- xml_parser_create_ns — Δημιουργεί ένα XML parser με υποστήριξη namespace
- xml_parser_create — δημιουργεί έναν XML parser
- xml_parser_free — Ελευθερώνει έναν XML parser
- xml_parser_get_option — παίρνει τις επιλογές από έναν XML parser
- xml_parser_set_option — ορίζει επιλογές σε έναν XML parser
- xml_set_character_data_handler — ορίζει handler για δεδομένα χαρακτήρων
- xml_set_default_handler — ορίζει τον προκαθορισμένο handler
- xml_set_element_handler — ορίζει τα στοιχεία αρχής και τέλους των handlers
- xml_set_end_namespace_decl_handler — Ορίζει τον handler για δεδομένα χαρακτήρων
- xml_set_external_entity_ref_handler — ορίζει έναν external entity reference handler
- xml_set_notation_decl_handler — ορίζει τον notation declaration handler
- xml_set_object — Χρησιμοποιείστε τον XML Parser μέσα σε ένα object
- xml_set_processing_instruction_handler — Ορίζει τον processing instruction (PI) handler
- xml_set_start_namespace_decl_handler — Ορίζει τον character data handler
- xml_set_unparsed_entity_decl_handler — Ορίζει έναν αμεταγλώττιστο entity declaration handler