The PHP 5.0 DOM is very powerful to create and work on valid RSS Feeds. I found a easy to follow step-by-step-tutorial here:
http://xml-rss.de/xml-rss-feed-mit-php.htm
(in german language but the code can be understand in every language i think) maybe it helps someone to understand the DOM-Thing better. But beware it don´t work on PHP 4!
Fonctions DOM XML
Fonctions dépréciées
Il y a un groupe de fonctions qui ne sont pas compatibles avec les standards DOM et qui ne devraient plus être utilisées. Ces fonctions sont listées dans la table ci-dessous. La fonction DomNode_append_child() a vu son comportement changer. Désormais, elle ajoute un fils et non pas un frère. Si cela casse votre application, utilisez plutôt la fonction DomNode_append_sibling(), qui ne fait pas partie des standards.
| Ancienne fonction | Nouvelle fonction |
|---|---|
| xmldoc | domxml_open_mem() |
| xmldocfile | domxml_open_file() |
| domxml_new_xmldoc | domxml_new_doc() |
| domxml_dump_mem | DomDocument_dump_mem() |
| domxml_dump_mem_file | DomDocument_dump_file() |
| DomDocument_dump_mem_file | DomDocument_dump_file() |
| DomDocument_add_root | DomDocument_create_element() suivie de DomNode_append_child() |
| DomDocument_dtd | DomDocument_doctype() |
| DomDocument_root | DomDocument_document_element() |
| DomDocument_children | DomNode_child_nodes() |
| DomDocument_imported_node | Pas de remplacement. |
| DomNode_add_child | Créez un nouveau noeud avec DomDocument_create_element() puis ajoutez-le avec DomNode_append_child(). |
| DomNode_children | DomNode_child_nodes() |
| DomNode_parent | DomNode_parent_node() |
| DomNode_new_child | Créez un nouveau noeud avec DomDocument_create_element() puis ajoutez-le avec DomNode_append_child(). |
| DomNode_set_content | Créez un nouveau noeud avec DomDocument_create_text_node() puis ajoutez-le avec DomNode_append_child(). |
| DomNode_get_content | Le contenu est juste un noeud de texte, et est accessible via DomNode_child_nodes(). |
| DomNode_set_content | Le contenu est juste un noeud de texte, et peut être ajouté avec DomNode_append_child(). |
Classes
L'API de ce module suit le standard DOM niveau 2 aussi fidèlement que possible. Par conséquent, l'API est totalement orientée objet. C'est une bonne idée d'avoir les standards DOM disponibles sous la main, lorsque vous utilisez ce module. Bien que cette API soit orientée objet, il existe de nombreuses fonctions qui peuvent être appelées d'une manière non objet, en passant l'objet à utiliser comme premier argument de la fonction. Ces fonctions sont essentiellement conservées pour assurer la compatibilité avec les extensions plus anciennes, et ne doivent pas être utilisées.
Cette API diffère de l'API officielle DOM en deux points. Le premier est que tous les attributs des classes sont implémentées comme des fonctions du même nom. Le second est que les noms des fonctions suivent les standards PHP. Cela signifie que la fonction DOM lastChild() s'écrit en PHP last_child().
Ce module définit un grand nombre de classe, qui sont listés en incluant leur méthodes dans les tables suivantes. Les classes ayant un équivalent DOM sont préfixées par DOM.
| Nom de la classe | Classe parente |
|---|---|
| DomAttribute | DomNode |
| DomCData | DomNode |
| DomComment | DomCData : DomNode |
| DomDocument | DomNode |
| DomDocumentType | DomNode |
| DomElement | DomNode |
| DomEntity | DomNode |
| DomEntityReference | DomNode |
| DomProcessingInstruction | DomNode |
| DomText | DomCData : DomNode |
| Parser | Actuellement, toujours appelée DomParser |
| XPathContext |
| Nom de la méthode | Nom de la fonction | Remarques |
|---|---|---|
| doctype | DomDocument_doctype() | |
| document_element | DomDocument_document_element() | |
| create_element | DomDocument_create_element() | |
| create_text_node | DomDocument_create_text_node() | |
| create_comment | DomDocument_create_comment() | |
| create_cdata_section | DomDocument_create_cdata_section() | |
| create_processing_instruction | DomDocument_create_processing_instruction() | |
| create_attribute | DomDocument_create_attribute() | |
| create_entity_reference | DomDocument_create_entity_reference() | |
| get_elements_by_tagname | DomDocument_get_elements_by_tagname() | |
| get_element_by_id | DomDocument_get_element_by_id() | |
| dump_mem | DomDocument_dump_mem() | Non standard DOM |
| dump_file | DomDocument_dump_file() | Non standard DOM |
| html_dump_mem | DomDocument_html_dump_mem() | Non standard DOM |
| xpath_init | xpath_init | Non standard DOM |
| xpath_new_context | xpath_new_context | Non standard DOM |
| xptr_new_context | xptr_new_context | Non standard DOM |
| Nom de la méthode | Nom de la fonction | Remarques |
|---|---|---|
| tagname | DomElement_tagname() | |
| get_attribute | DomElement_get_attribute() | |
| set_attribute | DomElement_set_attribute() | |
| remove_attribute | DomElement_remove_attribute() | |
| get_attribute_node | DomElement_get_attribute_node() | |
| set_attribute_node | DomElement_set_attribute_node() | |
| get_elements_by_tagname | DomElement_get_elements_by_tagname() | |
| has_attribute | DomElement_has_attribute() |
| Nom de la méthode | Remarques |
|---|---|
| DomNode_node_name() | |
| DomNode_node_value() | |
| DomNode_node_type() | |
| DomNode_last_child() | |
| DomNode_first_child() | |
| DomNode_child_nodes() | |
| DomNode_previous_sibling() | |
| DomNode_next_sibling() | |
| DomNode_parent_node() | |
| DomNode_owner_document() | |
| DomNode_insert_before() | |
| DomNode_append_child() | |
| DomNode_append_sibling() | Non standard DOM. Cette fonction émule le comportement précédent de DomNode_append_child(). |
| DomNode_remove_child() | |
| DomNode_has_child_nodes() | |
| DomNode_has_attributes() | |
| DomNode_clone_node() | |
| DomNode_attributes() | |
| DomNode_unlink_node() | Non standard DOM |
| DomNode_replace_node() | Non standard DOM |
| DomNode_set_content() | Non standard DOM, déprécié |
| DomNode_get_content() | Non standard DOM, déprécié |
| DomNode_dump_node() | Non standard DOM |
| DomNode_is_blank_node() | Non standard DOM |
| Nom de la méthode | Remarques | |
|---|---|---|
| name | DomAttribute_name() | |
| value | DomAttribute_value() | |
| specified | DomAttribute_specified() |
| Nom de la méthode | Nom de la fonction | Remarques |
|---|---|---|
| target | DomProcessingInstruction_target() | |
| data | DomProcessingInstruction_data() |
| Nom de la méthode | Nom de la fonction | Remarques |
|---|---|---|
| add_chunk | Parser_add_chunk() | |
| end | Parser_end() |
| Nom de la méthode | Nom de la fonction | Remarques |
|---|---|---|
| eval | XPathContext_eval() | |
| eval_expression | XPathContext_eval_expression() | |
| register_ns | XPathContext_register_ns() |
| Nom de la méthode | Nom de la fonction | Remarques |
|---|---|---|
| name | DomDocumentType_name() | |
| entities | DomDocumentType_entities() | |
| notations | DomDocumentType_notations() | |
| public_id | DomDocumentType_public_id() | |
| system_id | DomDocumentType_system_id() | |
| internal_subset | DomDocumentType_internal_subset() |
Les classes DomDtd sont dérivées de DomNode. DomComment est dérivée de DomCData.
Exemples
De nombreux exemples de cette partie requièrent une chaîne XML. Au lieu de répéter la chaîne dans tous les exemples, elle sera mise dans un fichier, qui sera inclus dans tous les exemples. Ce fichier inclus sera utilisé dans les exemples suivants dans cette section. Alternativement, vous pouvez créer un document XML et le lire avec la fonction DomDocument_open_file().
Exemple #1 Fichier d'inclusion example.inc pour la chaîne XML d'exemple
<?php
$xmlstr = "<?xml version='1.0' standalone='yes'?>
<!DOCTYPE chapter SYSTEM '/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd'
[ <!ENTITY sp \"spanish\">
]>
<!-- lsfj -->
<chapter language='en'><title language='en'>Title</title>
<para language='ge'>
&sp;
<!-- comment -->
<informaltable ID='findme' language='&sp;'>
<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>
</chapter>";
?>
Sommaire
- DomAttribute->name — Retourne le nom de l'attribut
- DomAttribute->set_value — Spécifie une valeur à un attribut
- DomAttribute->specified — Vérifie si un attribut est spécifié
- DomAttribute->value — Retourne la valeur d'un attribut
- DomDocument->add_root — Ajoute un noeud
- DomDocument->create_attribute — Crée un nouvel attribut
- DomDocument->create_cdata_section — Crée un nouveau noeud CDATA
- DomDocument->create_comment — Crée un nouveau noeud de commentaire
- DomDocument->create_element_ns — Crée un nouvel élément avec un espace de noms associé
- DomDocument->create_element — Crée un nouveau noeud élément
- DomDocument->create_entity_reference — Crée une entité référence
- DomDocument->create_processing_instruction — Crée un nouveau noeud de traitement d'instructions (PI)
- DomDocument->create_text_node — Crée un nouveau noeud de texte
- DomDocument->doctype — Retourne le type de document
- DomDocument->document_element — Retourne le noeud racine d'un document DOM XML
- DomDocument->dump_file — Convertit un document DOM XML en fichier
- DomDocument->dump_mem — Convertit l'arbre XML interne en une chaîne de caractères
- DomDocument->get_element_by_id — Recherche un élément avec son identifiant
- DomDocument->get_elements_by_tagname — Retourne un tableau avec noeuds pour le nom de balise donné dans le document ou un tableau vide si non trouvé
- DomDocument->html_dump_mem — Convertit l'arbre XML interne en une chaîne de caractères au format HTML
- DomDocument->xinclude — Remplace XIncludes dans un objet DomDocument
- DomDocumentType->entities() — Retourne la liste des entités
- DomDocumentType->internal_subset() — Retourne le sous ensemble interne (internal subset)
- DomDocumentType->name() — Retourne le nom du type de document
- DomDocumentType->notations() — Retourne la liste des notations
- DomDocumentType->public_id() — Retourne l'identifiant public du type de document
- DomDocumentType->system_id() — Retourne l'identifiant système du type de document
- DomElement->get_attribute_node() — Retourne la valeur d'un attribut
- DomElement->get_attribute() — Retourne la valeur d'un attribut
- DomElement->get_elements_by_tagname() — Lit les éléments par nom de balise
- DomElement->has_attribute() — Vérifie si un attribut existe
- DomElement->remove_attribute() — Supprime un attribut
- DomElement->set_attribute_node() — Ajoute un nouvel attribut
- DomElement->set_attribute() — Définie la valeur d'un attribut
- DomElement->tagname() — Retourne le nom de l'élément courant
- DomNode->add_namespace — Ajoute une déclaration d'espace de nom à un noeud
- DomNode->append_child — Ajoute un nouveau fils à la fin des enfants
- DomNode->append_sibling — Ajoute un frère à un noeud
- DomNode->attributes — Retourne la liste des attributs
- DomNode->child_nodes — Retourne les fils d'un noeud
- DomNode->clone_node — Clone un noeud
- DomNode->dump_node — Convertit un noeud en chaîne
- DomNode->first_child — Retourne le premier fils du noeud
- DomNode->get_content — Retourne le contenu du noeud
- DomNode->has_attributes — Vérifie si un noeud a des attributs
- DomNode->has_child_nodes — Vérifie si un noeud a des fils
- DomNode->insert_before — Insère un nouveau noeud fils
- DomNode->is_blank_node — Vérifie si un noeud est blanc
- DomNode->last_child — Retourne le dernier fils du noeud
- DomNode->next_sibling — Retourne le prochain noeud frère
- DomNode->node_name — Retourne le nom du noeud
- DomNode->node_type — Retourne le type de noeud
- DomNode->node_value — Retourne la valeur d'un noeud
- DomNode->owner_document — Retourne le document auquel appartient ce noeud DOM XML
- DomNode->parent_node — Retourne le père d'un noeud DOM XML
- DomNode->prefix — Retourne le préfixe d'espace de nom d'un noeud
- DomNode->previous_sibling — Retourne le frère précédent d'un noeud
- DomNode->remove_child — Supprime un fils de la liste des noeuds fils
- DomNode->replace_child — Remplace un noeud fils
- DomNode->replace_node — Remplace un noeud DomXML
- DomNode->set_content — Modifie le contenu d'un noeud
- DomNode->set_name — Modifie le nom d'un noeud
- DomNode->set_namespace — Modifie l'espace de noms d'un noeud
- DomNode->unlink_node — Efface un noeud
- DomProcessingInstruction->data — Retourne les données du noeud l'instruction en cours
- DomProcessingInstruction->target — Retourne la cible du noeud de l'instruction en cours
- DomXsltStylesheet->process() — Applique une transformation XSLT à un objet domdocument
- DomXsltStylesheet->result_dump_file() — Écrit le résultat d'un transformation XSLT dans un fichier
- DomXsltStylesheet->result_dump_mem() — Écrit le résultat d'un transformation XSLT dans une chaîne
- domxml_new_doc — Crée un document XML vide
- domxml_open_file — Crée un objet DOM à partir d'un fichier XML
- domxml_open_mem — Crée un objet DOM pour un document XML
- domxml_version — Lit le numéro de version de la bibliothèque XML
- domxml_xmltree — Crée un arbre d'objets PHP à partir d'un document XML
- domxml_xslt_stylesheet_doc — Crée un objet DomXsltStylesheet à partir d'un objet DomDocument
- domxml_xslt_stylesheet_file — Crée un objet DomXsltStylesheet à partir d'un document XSL dans un fichier
- domxml_xslt_stylesheet — Crée un objet DomXsltStylesheet à partir d'un document XSL dans une chaîne
- domxml_xslt_version — Lit le numéro de version de la bibliothèque XSLT
- xpath_eval_expression — Calcule un chemin XPath à partir d'une chaîne
- xpath_eval — Calcule un chemin XPath à partir d'une chaîne
- xpath_new_context — Crée un nouveau contexte xpath
- xpath_register_ns_auto — Sauvegarde l'espace de nom donné dans le contexte XPath passé
- xpath_register_ns — Sauvegarde l'espace de nom donné dans le contexte XPath passé
- xptr_eval — Calcul un chemin XPtr à partir d'une chaîne
- xptr_new_context — Crée un nouveau contexte XPath
Fonctions DOM XML
18-Jul-2008 01:55
04-Apr-2007 04:46
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
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;
}
?>
25-Jan-2006 01:05
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);
}
}
?>
13-Dec-2005 08:04
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;
}
}
}
11-Nov-2005 06:43
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
)
)
07-Jul-2005 09:57
If you want to subclass the domxml-classes, you have to use PHP5. It doesn't work with PHP4, and never will.
12-Feb-2005 01:33
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.
22-Dec-2004 02:54
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.
10-Dec-2004 05:15
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
16-Nov-2004 12:56
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>
<p>there are <? echo count($aData['contacts'][0]['contact']); ?>
contacts</p>
<p>the 2nd contact's phone number is
<?echo $aData['contacts'][0]['contact'][1]['phone'][0]['cdata']; ?>
</p>
<hr />
<p>Here is the raw array structure:</p>
<pre>
<? print_r($aData); ?>
</pre>
</body>
</html>
==================================================================
04-Jul-2004 06:48
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.
22-Apr-2004 08:05
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
28-Jan-2004 01:48
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>";
?>
24-Dec-2003 09:19
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
17-Dec-2003 11:41
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
11-Nov-2003 08:46
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<br>".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;
}
}
?>
09-Apr-2003 10:51
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
18-Mar-2003 12:38
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-
