PHP: XML �rtelmez� f�ggv�nyek - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links 
search for in the  
previouswddx_serialize_varsutf8_decodenext
Last updated: Fri, 30 Aug 2002
view the printer friendly version or the printer friendly version with notes or change language to English | Brazilian Portuguese | Chinese | Czech | Dutch | Finnish | French | German | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Swedish | Turkish

CV. XML �rtelmez� f�ggv�nyek

Bemutat�s

Az XML-r�l n�h�ny sz�ban

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 c�men tal�lhat�.

Install�l�s

Ez a kiterjeszt�s az expat k�nyvt�rat haszn�lja, amely a 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 $@
El�rhet� forr�s RPM csomag is a k�vetkez� helyen: , ha nem akarsz k�nl�dni a ford�t�ssal ;)

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�ltad.

A PHP telep�t�se.... Tada! Ezt kell(ene) l�tnod!

Err�l a b�v�tm�nyr�l

Ez a PHP b�v�tm�ny t�mogat�st ny�jt a James Clark �ltal �rt expat-hoz a PHP-ben. Ezzel az eszk�k�zslettel elemezhetsz, de nem �rv�nyes�thetsz XML dokumentumokat. H�romf�le forr�s karakter k�dol�st t�mogat, amit a PHP is: US-ASCII, ISO-8859-1 �s azUTF-8. Az UTF-16 nem t�mogatott.

Ezzel a b�v�tm�nnyel l�trehozhatsz XML elemz�ket madj defini�lhatsz "handler"-eket k�l�nf�le XML feladatokhoz. Mindegyik XML elemz�nek van n�h�ny param�tere amit be�ll�thasz.

Az XML esem�nykezel�k:

T�bl�zat 1. T�mogatott XML kezel�k (handler-ek)

PHP f�ggv�ny a handler be�ll�t�s�hozEvent description
xml_set_element_handler() Element events are issued whenever the XML parser encounters start or end tags. There are separate handlers for start tags and end tags.
xml_set_character_data_handler() Character data is roughly all the non-markup contents of XML documents, including whitespace between tags. Note that the XML parser does not add or remove any whitespace, it is up to the application (you) to decide whether whitespace is significant.
xml_set_processing_instruction_handler() PHP programmers should be familiar with processing instructions (PIs) already. <?php ?> is a processing instruction, where php is called the "PI target". The handling of these are application-specific, except that all PI targets starting with "XML" are reserved.
xml_set_default_handler() What goes not to another handler goes to the default handler. You will get things like the XML and document type declarations in the default handler.
xml_set_unparsed_entity_decl_handler() This handler will be called for declaration of an unparsed (NDATA) entity.
xml_set_notation_decl_handler() This handler is called for declaration of a notation.
xml_set_external_entity_ref_handler() This handler is called when the XML parser finds a reference to an external parsed general entity. This can be a reference to a file or URL, for example. See the external entity example for a demonstration.

Case Folding

The element handler functions may get their element names case-folded. Case-folding is defined by the XML standard as "a process applied to a sequence of characters, in which those identified as non-uppercase are replaced by their uppercase equivalents". In other words, when it comes to XML, case-folding simply means uppercasing.

By default, all the element names that are passed to the handler functions are case-folded. This behaviour can be queried and controlled per XML parser with the xml_parser_get_option() and xml_parser_set_option() functions, respectively.

Error Codes

The following constants are defined for XML error codes (as returned by 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

Character Encoding

PHP's XML extension supports the character set through different character encodings. There are two types of character encodings, source encoding and target encoding. PHP's internal representation of the document is always encoded with UTF-8.

Source encoding is done when an XML document is parsed. Upon creating an XML parser, a source encoding can be specified (this encoding can not be changed later in the XML parser's lifetime). The supported source encodings are ISO-8859-1, US-ASCII and UTF-8. The former two are single-byte encodings, which means that each character is represented by a single byte. UTF-8 can encode characters composed by a variable number of bits (up to 21) in one to four bytes. The default source encoding used by PHP is ISO-8859-1.

Target encoding is done when PHP passes data to XML handler functions. When an XML parser is created, the target encoding is set to the same as the source encoding, but this may be changed at any point. The target encoding will affect character data as well as tag names and processing instruction targets.

If the XML parser encounters characters outside the range that its source encoding is capable of representing, it will return an error.

If PHP encounters characters in the parsed XML document that can not be represented in the chosen target encoding, the problem characters will be "demoted". Currently, this means that such characters are replaced by a question mark.

Some Examples

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.

P�lda 1. Show XML Element Structure

$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 Tag Mapping Example

P�lda 2. Map XML to HTML

This example maps tags in an XML document directly to HTML tags. Elements not found in the "map array" are ignored. Of course, this example will only work with a specific XML document type.
$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);

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.)

P�lda 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 "&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($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);

?>

P�lda 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 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:

P�lda 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>

Tartalom
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 -- visszaadja az XML elemz� egy tipikus hib�j�hoz tartoz� sz�veget
xml_get_current_byte_index --  visszaadja az aktu�lis b�jtindexet egy XML elemz�h�z
xml_get_current_column_number --  visszaadja az aktu�lis oszlop sz�m�t egy XML elemz�h�z
xml_get_current_line_number -- visszaadja az aktu�lis sorindexet egy XML elemz�h�z
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 -- set up character data handler
xml_set_default_handler -- set up default handler
xml_set_element_handler -- set up start and end element handlers
xml_set_end_namespace_decl_handler --  Set up character data handler
xml_set_external_entity_ref_handler -- set up external entity reference handler
xml_set_notation_decl_handler -- set up notation declaration handler
xml_set_object -- Use XML Parser within an object
xml_set_processing_instruction_handler --  Set up processing instruction (PI) handler
xml_set_start_namespace_decl_handler --  Set up character data handler
xml_set_unparsed_entity_decl_handler --  Set up unparsed entity declaration handler
User Contributed Notes
XML �rtelmez� f�ggv�nyek
add a note about notes
[email protected]
12-Jan-1999 11:05

In the installation section, be sure that the indents in the code you add to the Makefile are tabs, not spaces. make will choke otherwise.

Additionally, you need to copy two header files into your /usr/local/include or equivalent:

$EXPAT_SRC/xmltok/xmltok.h
$EXPAT_SRC/xmlparse/xmlparse.h

[email protected]
07-Jul-1999 05:21

When using the XML parser, make sure you're not using the magic quotes option (e.g. use set_magic_quotes_runtime(0) if it's not the compiled default), otherwise you'll get 'not well-formed' errors when dealing with tags with attributes set in them.
[email protected]
16-Aug-1999 11:13

"The expat library should be installed somewhere your compiler can find it." is a little vague. Here is a quick install guide:
1) download expat.zip
2) mv expat.zip /dir/of/expat
3) unzip expat.zip
4) cd expat
5) Add these lines to Makefile:
libexpat.a: $(OBJS)
(tab) ar -rc $@ $(OBJS)
(tab) ran lib $@
6) make
7) cp libexpat.a /usr/local/lib
8) mkdir /usr/local/include/xml
9) cd xmlparse
10) cp *.h /usr/local/include/xml
11) cd ../xmltok
12) cp *.h /usr/local/include/xml
13) cd ../xmlwf
14) cp *.h /usr/local/include/xml
Then reconfigure and make php, then apache.

[email protected]
30-Oct-1999 05:40

I'm not sure if anyone else has had or will have this problem, but here is my solution. For some reason, the PHP compile did recognise the Apache 1.3.9 support for XML. I circumvented this by creating a link from /usr/local/include/xml to the Apache src/lib/expat-lite directory. I then however ran into problems with the Apache compile. It was looking for libexpat.a which hadn't been created. I tried to create this by downloading the source and modifying the Makefile, but it wasnt created for some reason. Finally, I resorted to creating the libexpat.a file by hand:

ar -rc xmltok/xmltok.o
ar -q xmltok/xmlrole.o
ar -q xmlwf/xmlwf.o
ar -q xmlwf/xmlfile.o
ar -q xmlwf/codepage.o
ar -q xmlparse/xmlparse.o
ar -q xmlparse/hashtable.o

I hope this helps someone, because it would have saved me a lot of time. Also note that I was getting an ANSI non-compliance error in the Apache build process. After added the -v swicth to line 2141 as pointed out in the FAQ, I found out it was the missing libexpat.a package.

[email protected]
15-Dec-1999 04:25

Remember, that when adding the lines for making:
libexpat.a: $(OBJS)
<tab> ar -rc $@ $(OBJS)
<tab> ranlib $@
,you'll have to do a "make libexpat.a" after running "make".

[email protected]
17-Feb-2000 06:31

The link is no active. For the expat.zip do a FTP file search.
[email protected]
28-Sep-2000 02:39

I've discovered some unusual behaviour in this API when ampersand entities are parsed in cdata; for some reason the parser breaks up the section around the entities, and calls the handler repeated times for each of the sections. If you don't allow for this oddity and you are trying to put the cdata into a variable, only the last part will be stored.

You can get around this with a line like:

$foo .= $cdata;

If the handler is called several times from the same tag, it will append them, rather than rewriting the variable each time. If the entire cdata section is returned, it doesn't matter.

May happen for other entities, but I haven't investigated.

Took me a while to figure out what was happening; hope this saves someone else the trouble.

[email protected]
06-Oct-2000 08:37

There's a really good article on XML parsing with PHP at
[email protected]
31-Mar-2001 01:35

Excellent IMHO XPath library for XML manipulation. Doesn't requires the XML libraries to be installed.
Take a look:

[email protected]
24-Jan-2002 03:43

I had to TRIM the data when I passed one large String containig a wellformed XML-File to xml_parse. The String was read by CURL, which aparently put a BLANK at the end of the String. This BLANK produced a "XML not wellformed"-Error in xml_parse!
jason@NOSPAM_projectexpanse_NOSPAM.com
26-Feb-2002 11:11

For newbies wanting a good tutorial on how to actually get started and where to go from this listing of functions, then visit:


It shows an excellent example of how to read the XML data into a class file so you can actually process it, not just display it all pretty-like, like many tutorials on PHP/XML seem to be doing.

[email protected]
22-Mar-2002 08:16

In reference to the note made by [email protected] about parsing entities:

I could be wrong, but since it is possible to define your own entities within an XML DTD, the cdata handler function parses these individually to allow for your own implementation of those entities within your cdata handler.

[email protected]
15-Apr-2002 09:23

I put up a good, simple, real world example of how to parse XML documents. While the sample grabs stock quotes off of the web, you can tweak it to do whatever you need.


[email protected]
14-Aug-2002 08:59

[Editor's note: see also xml_parse_into_struct().]

Very simple routine to convert an XML file into a PHP structure. $obj->xml contains the resulting PHP structure. I would be interested if someone could suggest a cleaner method than the evals I am using.

<?
$filename = 'sample.xml';
$obj->tree = '$obj->xml';
$obj->xml = '';

function startElement($parser, $name, $attrs) {
global $obj;

// If var already defined, make array
eval('$test=isset('.$obj->tree.'->'.$name.');');
if ($test) {
eval('$tmp='.$obj->tree.'->'.$name.';');
eval('$arr=is_array('.$obj->tree.'->'.$name.');');
if (!$arr) {
eval('unset('.$obj->tree.'->'.$name.');');
eval($obj->tree.'->'.$name.'[0]=$tmp;');
$cnt = 1;
}
else {
eval('$cnt=count('.$obj->tree.'->'.$name.');');
}

$obj->tree .= '->'.$name."[$cnt]";
}
else {
$obj->tree .= '->'.$name;
}
if (count($attrs)) {
eval($obj->tree.'->attr=$attrs;');
}
}

function endElement($parser, $name) {
global $obj;
// Strip off last ->
for($a=strlen($obj->tree);$a>0;$a--) {
if (substr($obj->tree, $a, 2) == '->') {
$obj->tree = substr($obj->tree, 0, $a);
break;
}
}
}

function characterData($parser, $data) {
global $obj;

eval($obj->tree.'->data=\''.$data.'\';');
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($filename, "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);
print_r($obj->xml);
return 0;

?>

add a note about notes
previouswddx_serialize_varsutf8_decodenext
Last updated: Fri, 30 Aug 2002
show source | credits | stats | mirror sites
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Wed Sep 4 00:18:56 2002 CEST