Forum und email

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 $@
Το source RPM πακέτο της expat μπορείτε να το βρείτε στο » https://sourceforge.net/projects/expat/.

Εγκατάσταση

Αυτές οι συναρτήσεις είναι ενεργοποιημένες 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 που έχουν οριστεί είναι:

XML handlers που υποστηρίζονται
Συνάρτηση της 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($fp4096)) {
    if (!
xml_parse($xml_parser$datafeof($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 Tags

Example#2 Αντιστοιχία XML σε HTML

Αυτό το παράδειγμα αντιστοιχεί τα tags σε ένα XML αρχείο κατευθείαν σε HTML tags. Τα Elements που δεν υπάρχουν στον "map array" αγνοούνται. Φυσικά, αυτό το παράδειγμα θα δουλέψει με ένα συγκεκριμένο 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_parserXML_OPTION_CASE_FOLDINGtrue);
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($fp4096)) {
    if (!
xml_parse($xml_parser$datafeof($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 
"&lt;<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 
"&gt;";
}

function 
endElement($parser$name) {
    print 
"&lt;/<font color=\"#0000cc\">$name</font>&gt;";
}

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($data01) == "&" && substr($data, -11) == ";") {
        
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($fp4096)) {
            if (!
xml_parse($parser$datafeof($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_parserXML_OPTION_CASE_FOLDING1);
    
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($fp4096)) {
    if (!
xml_parse($xml_parser$datafeof($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