|
DOM XML FunctionsThe DOM XML extension has been overhauled in PHP 4.3.0 to better comply with the DOM standard. The extension still contains many old functions, but they should no longer be used. In particular, functions that are not object-oriented should be avoided. The extension allows you to operate on an XML document with the DOM API. It also provides a function domxml_xmltree() to turn the complete XML document into a tree of PHP objects. Currently, this tree should be considered read-only - you can modify it, but this would not make any sense since DomDocument_dump_mem() cannot be applied to it. Therefore, if you want to read an XML file and write a modified version, use DomDocument_create_element(), DomDocument_create_text_node(), set_attribute(), etc. and finally the DomDocument_dump_mem() function.
Note:
This extension has been moved to the » PECL repository and is no longer bundled with PHP as of PHP 5.0.0. This extension makes use of the » GNOME XML library. Download and install this library. You will need at least libxml-2.4.14. To use DOM XSLT features you can use the » libxslt library and EXSLT enhancements from » http://www.exslt.org/. Download and install these libraries if you plan to use (enhanced) XSLT features. You will need at least libxslt-1.0.18. This » PECL extension is not bundled with PHP. Information for installing this PECL extension may be found in the manual chapter titled Installation of PECL extensions. Additional information such as new releases, downloads, source files, maintainer information, and a CHANGELOG, can be located here: » http://pecl.php.net/package/domxml.
In PHP 4 this PECL extensions
source can be found in the
Windows users will enable There are quite a few functions that do not fit into the DOM standard and should no longer be used. These functions are listed in the following table. The function DomNode_append_child() has changed its behaviour. It now adds a child and not a sibling. If this breaks your application, use the non-DOM function DomNode_append_sibling(). Table 67. Deprecated functions and their replacements
The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime. Table 68. XML constants
The API of the module follows the DOM Level 2 standard as closely as possible. Consequently, the API is fully object-oriented. It is a good idea to have the DOM standard available when using this module. Though the API is object-oriented, there are many functions which can be called in a non-object-oriented way by passing the object to operate on as the first argument. These functions are mainly to retain compatibility to older versions of the extension, and should not be used when creating new scripts. This API differs from the official DOM API in two ways. First, all class attributes are implemented as functions with the same name. Secondly, the function names follow the PHP naming convention. This means that a DOM function lastChild() will be written as last_child(). This module defines a number of classes, which are listed - including their method - in the following tables. Classes with an equivalent in the DOM standard are named DOMxxx. Table 69. List of classes
Table 70. DomDocument class (DomDocument : DomNode)
Table 71. DomElement class (DomElement : DomNode)
Table 72. DomNode class
Table 73. DomAttribute class (DomAttribute : DomNode)
Table 74. DomProcessingInstruction class (DomProcessingInstruction : DomNode)
Table 75. Parser class
Table 76. XPathContext class
Table 77. DomDocumentType class (DomDocumentType : DomNode)
The classes DomDtd is derived from DomNode. DomComment is derived from DomCData. Many examples in this reference require an XML string. Instead of repeating this string in every example, it will be put into a file which will be included by each example. This include file is shown in the following example section. Alternatively, you could create an XML document and read it with DomDocument_open_file(). Example 547. Include file example.inc with XML string<?php Table of Contents
Code Examples / Notes » ref.domxmldeborah dot seidman
You can always use a sax parser (expat) which saves on memory storage (there is none as sax is event driven) and use this neat code to produce an array structure of you xml file : see http://fr2.php.net/manual/fr/function.xml-parse.php comment by tgrabietz at bupnet dot de 22-Sep-2004 05:05 sorn
When parsing "iso-8859-1" encoded XML files, use "utf8_decode" to recover node contents (libxml uses "UTF-8" internal encoding, so conversion needed). --- BEGIN: mydata.xml --- <?xml version="1.0" encoding="iso-8859-1"?> ... --- END: mydata.xml--- --- BEGIN: myparser.php --- <?php ... $domxml = domxml_open_file("mydata.xml")); ... $content = utf8_decode(trim($node->content)); echo $content; ... ?> --- END: myparser.php -eof- sam
When installing PHP --with-dom and --with-dom-xslt on a Red Hat 9.0 remember to install the following packages: libxml libxml2 libxml2-devel libxslt libxslt-devel Then you will be spared error messages when trying to configure. regards SAM bart
This recursive function will iterate over a DOM object and display it as a nicely formatted XML structure. I used intuitive variable names to help learn more about the DOM functions and their return values. <<?php function PrintDomTree($DomNode) { if ($ChildDomNode = $DomNode->first_child()) { static $depth = 0; $whitespace = "\n ".str_repeat(" ", ($depth * 2)); while ($ChildDomNode) { if ($ChildDomNode->node_type() == XML_TEXT_NODE) { echo trim($ChildDomNode->node_value()); } elseif ($ChildDomNode->node_type() == XML_ELEMENT_NODE) { $HasTag = 1; echo $whitespace; echo "<", $ChildDomNode->node_name(); if ($ChildDomNode->has_attributes()) { $Array = $ChildDomNode->attributes(); foreach ($Array AS $DomAttribute) { echo " ", $DomAttribute->name(), "=\"", $DomAttribute->value(), "\""; } } echo ">"; if ($ChildDomNode->has_child_nodes()) { $depth++; if (PrintDomTree($ChildDomNode)) { echo $whitespace; } $depth--; } echo "</", $ChildDomNode->node_name(), ">"; } $ChildDomNode = $ChildDomNode->next_sibling(); } return $HasTag; } } ?> ngc dontspamme rapanden spamoff dk
Sorry, a bug in my code... I made the first version late at night, sorry! The bug was in the "if ($ChildDomNode->has_child_nodes())" block, I didn't save the data for the for the CildNode of the CildNodes. the bug has been fixed. <?php function getElementAttributes($DomNode,$elementName,$attriName) { if ($ChildDomNode = $DomNode->first_child()) { while($ChildDomNode) { if ($ChildDomNode->node_type() == XML_ELEMENT_NODE) { if($ChildDomNode->node_name() == $elementName) { if ($ChildDomNode->has_attributes()) { $Array = $ChildDomNode->attributes(); foreach ($Array AS $DomAttribute) { if($DomAttribute->name() == $attriName) { $nodeArray[] = $DomAttribute->value(); } }// foreach ($Array AS $DomAttribute) }//if ($ChildDomNode->has_attributes()) } if ($ChildDomNode->has_child_nodes()) { $tmpArray = (getElementAttributes($ChildDomNode,$elementName,$attriName)); $nodeArray = array_merge($nodeArray, $tmpArray); unset($tmpArray); }// if ($ChildDomNode->has_child_nodes()) }//if ($ChildDomNode->node_type() == XML_ELEMENT_NODE) $ChildDomNode = $ChildDomNode->next_sibling(); }//while($ChildDomNode) return $nodeArray; }//if ($ChildDomNode = $DomNode->first_child()) } $file = "test3.xml"; $element = "pb"; $att = "id"; $DomDocument = domxml_open_file($file); $RootDomNode = $DomDocument->document_element(); $array = getElementAttributes($RootDomNode,$element,$att); echo "<pre>"; print_r($array); echo "</pre>"; ?> 01-dec-2006 04:05
Referenced array functions drive me crazy for one reason or another (personal issue I guess). So for any others like me, here's my modification (thanks to the original posters below for the base to work on!) I haven't tested this on much more than simple XML files, so there's probably a few ways to break this - I'm also thinking this could probably be rewritten to be more efficient also, but it's working quite well for me thus far. <?php function xml2array($domnode) { $nodearray = array(); $domnode = $domnode->firstChild; while (!is_null($domnode)) { $currentnode = $domnode->nodeName; switch ($domnode->nodeType) { case XML_TEXT_NODE: if(!(trim($domnode->nodeValue) == "")) $nodearray['cdata'] = $domnode->nodeValue; break; case XML_ELEMENT_NODE: if ($domnode->hasAttributes() ) { $elementarray = array(); $attributes = $domnode->attributes; foreach ($attributes as $index => $domobj) { $elementarray[$domobj->name] = $domobj->value; } } break; } if ( $domnode->hasChildNodes() ) { $nodearray[$currentnode][] = xml2array($domnode); if (isset($elementarray)) { $currnodeindex = count($nodearray[$currentnode]) - 1; $nodearray[$currentnode][$currnodeindex]['@'] = $elementarray; } } else { if (isset($elementarray) && $domnode->nodeType != XML_TEXT_NODE) { $nodearray[$currentnode]['@'] = $elementarray; } } $domnode = $domnode->nextSibling; } return $nodearray; } ?> squiz
Re: websiterepairguys... Close but no cigar ;-) As written it will not work if the repeated tags are somewhere other than the first node, i.e. the following will not work: <nodes> <node>onething</node> <node>something</node> <node>something</node> </nodes> You must store the new node name when you get a new sibling that doesn't match the previous and then it will work OK. Amended code: function dom_to_array($domnode, &$array) { $parent=$domnode; $domnode = $domnode->firstChild; $myname=$domnode->nodeName; $x=1; while (!is_null($domnode)) { switch ($domnode->nodeType) { case XML_ELEMENT_NODE: { if ( !$domnode->hasChildNodes()) { $array[$domnode->nodeName]=''; } else if ( $domnode->hasChildNodes() && $domnode->firstChild->nodeType==XML_TEXT_NODE) { $array[$domnode->nodeName]=$domnode->firstChild->nodeValue; } else if ( $domnode->hasChildNodes() ) { $array_ptr = & $array[$domnode->nodeName]; dom_to_array($domnode, $array_ptr); } break; } } $domnode = $domnode->nextSibling; if($domnode->nodeName == $myname) { $domnode->nodeName.=($x++); } else { $myname = $domnode->nodeName; } } } alex
PHP4/DOMXML code is not compatible with the new PHP5/dom extension. While the conversion is quite strait forward, it can take a long time if domxml has been broadly used. Moreover, it can be interesting to have old PHP4 scripts ready for PHP5 as soon as possible even if the server is still running PHP4. Since I have that kind of problem, if have written a small library to include in PHP4 scripts to enable them to be run on PHP5. http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/ It does not cover all the domxml functionality, but most of the main functions and can easily be extended. Tested with PHP4.3.7 and PHP5.0.0RC3 but I will try to keep it updated. I hope it can help. palatinusz - karoly_szalkary
My short way of parsing an XML document, for example displaying the document in a structured form: <?php $indent = ""; $file = "semi.xml"; $showfile = file_get_contents("c:/Program Files/Apache Group/apache/htdocs/phpxml" . "/" . $file); // whatever path // maybe the whole path is not important, look it up in other posts $newstring=utf8_encode($showfile); // it's important! if(!$domDocument = domxml_open_mem($newstring)) { echo "Couldn't load xml..."; exit; } $rootDomNode = $domDocument->document_element(); print "<pre>"; printElements($rootDomNode); print "</pre>"; function printElements($domNode) { if($domNode) { global $indent; if($domNode->node_type() == XML_ELEMENT_NODE) { print "<br />".$indent."<".$domNode->node_name(); if($domNode->has_attributes()) { $attributes = $domNode->attributes(); foreach($attributes as $domAttribute) { print " $domAttribute->name=\"$domAttribute->value\""; } } print ">"; if($domNode->has_child_nodes()) { $indent.=" "; $nextNode = $domNode->first_child(); printElements($nextNode); $indent= substr($indent, 0, strlen($indent)-2); print "<br />".$indent."<"."/".$domNode->node_name().">"; } else { print "$domNode->node_value()</".$domNode->node_name().">"; } } $nextNode = $domNode->next_sibling(); printElements($nextNode); } } ?> nospam
If you're having trouble understanding how the the DOM XML extension fits together you may find the UML diagram here helps: http://www.phppatterns.com/index.php/article/articleview/38
timo dot hummel
If you want to subclass the domxml-classes, you have to use PHP5. It doesn't work with PHP4, and never will.
steve
If you are using apache, instead of copying files around (iconv.dll for instance) you can use this in your httpd.conf for apache: LoadFile "d:/php/dlls/iconv.dll" I placed this line before LoadModule php4_module "d:/php/sapi/php4apache2.dll" and it worked, no copying of files or anything therefore helps when updating php, don't have to mess around searching for files and other stuff. bps7j
I've also rolled my own DOM-like functionality for places where the DOM extensions aren't available. http://www.sequent.org/baron/script-hacking.php websiterepairguys
I tried using the dom_to_simple_array that the user jas posted above, but it didnt work very well. The problems were it didnt handle sibling nodes with the same name, such as: <nodes> <node>something</node> <node>something</node> </nodes> Also, when it built child arrays from child nodes, it always interjected an wrapping array around the child, which isnt necessary. Here is the patched code: function dom_to_array($domnode, &$array) { $parent=$domnode; $domnode = $domnode->firstChild; $myname=$domnode->nodeName; $x=1; while (!is_null($domnode)) { switch ($domnode->nodeType) { case XML_ELEMENT_NODE: { if ( !$domnode->hasChildNodes()) { $array[$domnode->nodeName]=''; } else if ( $domnode->hasChildNodes() && $domnode->firstChild->nodeType==XML_TEXT_NODE) { $array[$domnode->nodeName]=$domnode->firstChild->nodeValue; } else if ( $domnode->hasChildNodes() ) { $array_ptr = & $array[$domnode->nodeName]; dom_to_array($domnode, $array_ptr); break; } } } $domnode = $domnode->nextSibling; if($domnode->nodeName==$myname) { $domnode->nodeName.=($x++); } } } snippet of array produced by this: [admin] => Array ( [menu] => Array ( [title] => Page Manager [view] => list ) [files] => Array ( [filename] => modules/testmodule/testmodule.php [filename1] => modules/testmodule/testmodule.xml [filename2] => media/lang/en-us/templates/testmodule.tpl ) ) ndaniel
I recently developed a script for parsing DHL XML transaction responses - finding it a pain in the rear to actually parse the XML and set my variables - it actually wasn't that hard once I figured it out - and it goes something like this... <?php // Use with a class containing functions set_attributes() and // set_data(). Use the following to set variables from the // resulting xml. $node is a dom xml object - in the first call // to loop, $node would be equal to the root document // element. function loop($node) { // set attribute tags here if ($node->has_attributes()) { $this->set_attributes($node); } // end if node has attributes if ($node->has_child_nodes()) { $this->loop($node->first_child()); } // end if node has child else { $this->set_data($node); } // end if node has no child // get next sibling $node = $node->next_sibling(); if ($node) { $this->loop($node); } // end if node } // end function loop ?> The code goes from the root element, if the element has attributes - it sets attribute variables. Second, it recursively proceeds to the lowest level element (no more children). Once that level has been reached, data variables are set. The next step goes to the next sibling of the element, if it exists. If the next sibling does not exists, the function is ended and the current element is returned to the parent element. The parent element is then checked for siblings. This process continues (as is with recursion) until the parent element is back at the root element, which is the end of the document. jas
i needed to have an easy way to create a multi-dimensional but EXTREMELY SIMPLE php array out of some XML text i'm receiving. NOT an object. just an ARRAY. i found that as simple a request as this seemed to be, the new (php5) DOM functions do not provide this functionality. even the SimpleXML functions are object-oriented, which doesn't work for some of my purposes (sending to a Smarty template variable for looping through, etc.) -- returning attributes as SimpleXMLElement objects instead of strings, etc.. i just wanted an ARRAY containing the data as STRINGS. eli (http://www.hoktar.com) had submitted such code earlier, based on domxml/php4 calls. his function was called "domxml_xmlarray". but when php5 came out, eli's comments at the bottom of the PHP site got erased. (fortunately, i had already saved his code.) no doubt, mine will too w/next version.. furthermore, as far as i can tell, no one has taken the cue to add something like eli's domxml_xmlarray function directly into the DOMDocument object (but it would be nice). so i translated eli's code, now using the dom calls (instead of the older domxml calls), and renamed the function to "dom_to_simple_array()". below is a script containing the function itself as well as an example of its use. just copy it to your server somewhere and execute it and it should work right off the bat if you are using php5. thanks. jeff stern ================================================================== <?php function dom_to_simple_array($domnode, &$array) { $array_ptr = &$array; $domnode = $domnode->firstChild; while (!is_null($domnode)) { if (! (trim($domnode->nodeValue) == "") ) { switch ($domnode->nodeType) { case XML_TEXT_NODE: { $array_ptr['cdata'] = $domnode->nodeValue; break; } case XML_ELEMENT_NODE: { $array_ptr = &$array[$domnode->nodeName][]; if ($domnode->hasAttributes() ) { $attributes = $domnode->attributes; if (!is_array ($attributes)) { break; } foreach ($attributes as $index => $domobj) { $array_ptr[$index] = $array_ptr[$domobj->name] = $domobj->value; } } break; } } if ( $domnode->hasChildNodes() ) { dom_to_simple_array($domnode, $array_ptr); } } $domnode = $domnode->nextSibling; } } # now, let's make a sample string containing some XML $strXMLData = "<contacts> <contact> <name> John Doe </name> <phone> 123-456-7890 </phone> </contact> <contact> <name> Mary Smiley </name> <phone> 567-890-1234 </phone> </contact> </contacts>"; # create a DOM tree xml object (hierarchical array) from # this XML string $domdoc = new DOMDocument; $domdoc->loadXML($strXMLData); # now simplify the DOM array into a very simple array structure # first, create an empty array to be filled with your # simplified array result.. $aData = array(); # now, pass the dom document and your empty array to the # converter function. dom_to_simple_array($domdoc, $aData); # now $aData contains your simplified array, so print it out ?><html> <body> there are <? echo count($aData['contacts'][0]['contact']); ?> contacts the 2nd contact's phone number is <?echo $aData['contacts'][0]['contact'][1]['phone'][0]['cdata']; ?> <hr /> Here is the raw array structure: <pre> <? print_r($aData); ?> </pre> </body> </html> ================================================================== gue-gue
Hi at All, if you use xpath_eval() you get a xpathobject with a type-member-variable, which tells you about the type of the found content. Here are the values and the corresponding types: 1 = XPATH_NODESET (integer) 2 = XPATH_BOOLEAN (integer) 3 = XPATH_NUMBER (integer) 4 = XPATH_STRING (integer) I think, but don't know, that the rest of the constants are: 0 = XPATH_UNDEFINED (integer) 5 = XPATH_POINT (integer) 6 = XPATH_RANGE (integer) 7 = XPATH_LOCATIONSET (integer) I hope i could help some people. Greetz, Chris bradparks
Hey; If you need to parse XML on an older version of PHP (e.g. 4.0) or if you can't get the expat extension enabled on your server, you might want to check out the Saxy and DOMIT! xml parsers from Engage Interactive. They're opensource and pure php, so no extensions or changes to your server are required. I've been using them for over a month on some projects with no problems whatsoever! Check em out at: DOMIT!, a DOM based xml parser, uses Saxy (included) http://www.engageinteractive.com/redir.php?resource=3&target=domit or Saxy, a sax based xml parser http://www.engageinteractive.com/redir.php?resource=4&target=saxy Brad |
Change Language.NET Functions Apache-specific Functions Alternative PHP Cache Advanced PHP debugger Array Functions Aspell functions [deprecated] BBCode Functions BCMath Arbitrary Precision Mathematics Functions PHP bytecode Compiler Bzip2 Compression Functions Calendar Functions CCVS API Functions [deprecated] Class/Object Functions Classkit Functions ClibPDF Functions [deprecated] COM and .Net (Windows) Crack Functions Character Type Functions CURL Cybercash Payment Functions Credit Mutuel CyberMUT functions Cyrus IMAP administration Functions Date and Time Functions DB++ Functions Database (dbm-style) Abstraction Layer Functions dBase Functions DBM Functions [deprecated] dbx Functions Direct IO Functions Directory Functions DOM Functions DOM XML Functions enchant Functions Error Handling and Logging Functions Exif Functions Expect Functions File Alteration Monitor Functions Forms Data Format Functions Fileinfo Functions filePro Functions Filesystem Functions Filter Functions Firebird/InterBase Functions Firebird/Interbase Functions (PDO_FIREBIRD) FriBiDi Functions FrontBase Functions FTP Functions Function Handling Functions GeoIP Functions Gettext Functions GMP Functions gnupg Functions Net_Gopher Haru PDF Functions hash Functions HTTP Hyperwave Functions Hyperwave API Functions i18n Functions IBM Functions (PDO_IBM) IBM DB2 iconv Functions ID3 Functions IIS Administration Functions Image Functions Imagick Image Library IMAP Informix Functions Informix Functions (PDO_INFORMIX) Ingres II Functions IRC Gateway Functions PHP / Java Integration JSON Functions KADM5 LDAP Functions libxml Functions Lotus Notes Functions LZF Functions Mail Functions Mailparse Functions Mathematical Functions MaxDB PHP Extension MCAL Functions Mcrypt Encryption Functions MCVE (Monetra) Payment Functions Memcache Functions Mhash Functions Mimetype Functions Ming functions for Flash Miscellaneous Functions mnoGoSearch Functions Microsoft SQL Server Functions Microsoft SQL Server and Sybase Functions (PDO_DBLIB) Mohawk Software Session Handler Functions mSQL Functions Multibyte String Functions muscat Functions MySQL Functions MySQL Functions (PDO_MYSQL) MySQL Improved Extension Ncurses Terminal Screen Control Functions Network Functions Newt Functions NSAPI-specific Functions Object Aggregation/Composition Functions Object property and method call overloading Oracle Functions ODBC Functions (Unified) ODBC and DB2 Functions (PDO_ODBC) oggvorbis OpenAL Audio Bindings OpenSSL Functions Oracle Functions [deprecated] Oracle Functions (PDO_OCI) Output Control Functions Ovrimos SQL Functions Paradox File Access Parsekit Functions Process Control Functions Regular Expression Functions (Perl-Compatible) PDF Functions PDO Functions Phar archive stream and classes PHP Options&Information POSIX Functions Regular Expression Functions (POSIX Extended) PostgreSQL Functions PostgreSQL Functions (PDO_PGSQL) Printer Functions Program Execution Functions PostScript document creation Pspell Functions qtdom Functions Radius Rar Functions GNU Readline GNU Recode Functions RPM Header Reading Functions runkit Functions SAM - Simple Asynchronous Messaging Satellite CORBA client extension [deprecated] SCA Functions SDO Functions SDO XML Data Access Service Functions SDO Relational Data Access Service Functions Semaphore SESAM Database Functions PostgreSQL Session Save Handler Session Handling Functions Shared Memory Functions SimpleXML functions SNMP Functions SOAP Functions Socket Functions Standard PHP Library (SPL) Functions SQLite Functions SQLite Functions (PDO_SQLITE) Secure Shell2 Functions Statistics Functions Stream Functions String Functions Subversion Functions Shockwave Flash Functions Swish Functions Sybase Functions TCP Wrappers Functions Tidy Functions Tokenizer Functions Unicode Functions URL Functions Variable Handling Functions Verisign Payflow Pro Functions vpopmail Functions W32api Functions WDDX Functions win32ps Functions win32service Functions xattr Functions xdiff Functions XML Parser Functions XML-RPC Functions XMLReader functions XMLWriter Functions XSL functions XSLT Functions YAZ Functions YP/NIS Functions Zip File Functions Zlib Compression Functions |