Next version xml2assoc with some improve fixes:
- no doubled data
- no buffer arrays
<?php
/*
Read XML structure to associative array
--
Using:
$xml = new XMLReader();
$xml->open([XML file]);
$assoc = xml2assoc($xml);
$xml->close();
*/
function xml2assoc($xml) {
$assoc = null;
while($xml->read()){
switch ($xml->nodeType) {
case XMLReader::END_ELEMENT: return $assoc;
case XMLReader::ELEMENT:
$assoc[$xml->name][] = array('value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
if($xml->hasAttributes){
$el =& $assoc[$xml->name][count($assoc[$xml->name]) - 1];
while($xml->moveToNextAttribute()) $el['attributes'][$xml->name] = $xml->value;
}
break;
case XMLReader::TEXT:
case XMLReader::CDATA: $assoc .= $xml->value;
}
}
return $assoc;
}
?>
The XMLReader class
Einführung
Die XMLReader-Erweiterung ist ein fortschreitender XML-Parser. Der Reader agiert wie ein Zeiger, der einen Datenstrom durchläuft und jeden vorbeikommenden Knoten der Reihe nach verarbeitet.
Klassenbeschreibung
Eigenschaften
- attributeCount
-
The number of attributes on the node
- baseURI
-
The base URI of the node
- depth
-
Depth of the node in the tree, starting at 0
- hasAttributes
-
Indicates if node has attributes
- hasValue
-
Indicates if node has a text value
- isDefault
-
Indicates if attribute is defaulted from DTD
- isEmptyElement
-
Indicates if node is an empty element tag
- localName
-
The local name of the node
- name
-
The qualified name of the node
- namespaceURI
-
The URI of the namespace associated with the node
- nodeType
-
The node type for the node
- prefix
-
The prefix of the namespace associated with thenode
- value
-
The text value of the node
- xmlLang
-
The xml:lang scope which the node resides
Vordefinierte Konstanten
XMLReader Node Types
- XMLReader::NONE
-
No node type
- XMLReader::ELEMENT
-
Start element
- XMLReader::ATTRIBUTE
-
Attribute node
- XMLReader::TEXT
-
Text node
- XMLReader::CDATA
-
CDATA node
- XMLReader::ENTITY_REF
-
Entity Reference node
- XMLReader::ENTITY
-
Entity Declaration node
- XMLReader::PI
-
Processing Instruction node
- XMLReader::COMMENT
-
Comment node
- XMLReader::DOC
-
Document node
- XMLReader::DOC_TYPE
-
Document Type node
- XMLReader::DOC_FRAGMENT
-
Document Fragment node
- XMLReader::NOTATION
-
Notation node
- XMLReader::WHITESPACE
-
Whitespace node
- XMLReader::SIGNIFICANT_WHITESPACE
-
Significant Whitespace node
- XMLReader::END_ELEMENT
-
End Element
- XMLReader::END_ENTITY
-
End Entity
- XMLReader::XML_DECLARATION
-
XML Declaration node
XMLReader Parser Options
- XMLReader::LOADDTD
-
Load DTD but do not validate
- XMLReader::DEFAULTATTRS
-
Load DTD and default attributes but do not validate
- XMLReader::VALIDATE
-
Load DTD and validate while parsing
- XMLReader::SUBST_ENTITIES
-
Substitute entities and expand references
Inhaltsverzeichnis
- XMLReader->close — XMLReader-Eingabe beenden
- XMLReader->expand — Gibt eine Kopie des aktullen Knotens als DOM-Objekt zurück
- XMLReader->getAttribute — Gibt den Wert eines Attributes nach Namen zurück
- XMLReader->getAttributeNo — Gibt den Wert eines Attributes nach Position zurück
- XMLReader->getAttributeNs — Gibt den Wert eines Attributes nach lokalem Namen und URI zurück
- XMLReader->getParserProperty — Zeigt an, ob die angegebene Eigenschaft gesetzt wurde
- XMLReader->isValid — Zeigt an, ob das geparste Dokument valide ist
- XMLReader->lookupNamespace — Prüfen, ob ein Namensbereich für einen Präfix vorhanden ist
- XMLReader->moveToAttribute — Zeiger auf benanntes Attribut setzen
- XMLReader->moveToAttributeNo — Zeiger auf Attribut nach Position setzen
- XMLReader->moveToAttributeNs — Zeiger auf benanntes Attribut im Namensraum setzen
- XMLReader->moveToElement — Zeiger positionieren auf das Elternelement des aktuellen Attributes
- XMLReader->moveToFirstAttribute — Zeiger auf erstes Attribut setzen
- XMLReader->moveToNextAttribute — Zeiger auf nächstes Attribut setzen
- XMLReader->next — Zeiger auf nächstes Element setzen und Kinder überspringen
- XMLReader->open — URI angeben, die auf XML-Inhalt verweist, der geparst werden soll
- XMLReader->read — Zeiger auf das nächste Element setzen
- XMLReader->setParserProperty — Parser-Optionen setzen
- XMLReader->setRelaxNGSchema — Dateiname oder URI des RelaxNG-Schema setzen
- XMLReader->setRelaxNGSchemaSource — Zeichenkette setzen, die RelaxNG-Schemadaten enthält
- XMLReader->XML — Zeichenkette setzen, deren Inhalt geparst werden soll
XMLReader
19-Jun-2008 03:51
16-Jun-2008 05:49
Given examples with xml2assoc() don't work with XML short tags (i.e. <tag attribute="somevalue" />). Looking for a solution.
12-Jun-2008 12:44
So I need to quickly process sections of a large XML file and I came up with this really dirty class file.
<?php
// Quick And Dirty XML to Array V 1.00
// Quick in speed, Dirty with the 2D non assoc array it makes.
// By: EllisGL 06/12/08
//
// Usuage:
// $xml = new XML_Fast_Parse($data=string, $section=string [, $callback=string][, $type=int]);
// $xml->parseIt();
//
// $data: Either a file location or string data
// $section: the section where you want to get data from
// $callback: Name of external function - this will process the array for each section
// $type: 0 for file, 1 for string data
class XML_QND
{
private $reader = "";
private $section = "";
private $callback = "";
function XML_Fast_Parse($data, $section, $callback="", $type=0)
{
$this->reader = new XMLReader();
$this->section = $section;
$this->callback = $callback;
if($type === 0)
{
// File
$this->reader->open($data);
}
else
{
// String
$this->reader->XML($data);
}
}
function parseIt()
{
while($this->reader->read())
{
if($this->reader->nodeType == 1 &&
$this->reader->localName == $this->section)
{
do
{
// Expand the rest of the data to text
$element = $this->reader->expand();
// Convert to an array
$arr = explode("\n", $element->textContent);
// Clean up the array...
foreach($arr as $key=>$val)
{
$arr[$key] = ltrim($val);
}
// Call back
$call = $this->callback;
$call($arr);
}while($this->reader->next('item_data'));
break;
}
}
return($arr);
}
}
set_time_limit(0);
function echoit($arr)
{
echo '<pre>';
print_r($arr);
echo '</pre>';
}
$data ='<?xml version="1.0" encoding="UTF-8" ?>
<DataFeeds>
<item_data>
<item_basic_data>
<item_unique_id>aaa</item_unique_id>
<item_sku>bbb</item_sku>
<item_upc>ccc</item_upc>
<item_mpn>ddd</item_mpn>
<item_brand>eee</item_brand>
</item_basic_data>
<merch_cat_list>
<merch_cat_item>
<merch_cat_name>fff</merch_cat_name>
</merch_cat_item>
<merch_cat_item>
<merch_cat_name>gggg</merch_cat_name>
</merch_cat_item>
</merch_cat_list>
</item_data>
<item_basic_data>
<item_unique_id>aaa</item_unique_id>
<item_sku>bbb</item_sku>
<item_upc>ccc</item_upc>
<item_mpn>ddd</item_mpn>
<item_brand>eee</item_brand>
</item_basic_data>
<merch_cat_list>
<merch_cat_item>
<merch_cat_name>fff</merch_cat_name>
</merch_cat_item>
<merch_cat_item>
<merch_cat_name>gggg</merch_cat_name>
</merch_cat_item>
</merch_cat_list>
</item_data>
</DataFeeds>';
$xml = new XML_QND($data, 'item_data', 'echoit', 1);
$xml->parseIt();
?>
02-Jun-2008 07:51
Fixes a bug in WebSee.Ru's xml2assoc function:
function xml2assoc($xml) {
$assoc = null;
while($xml->read()){
switch ($xml->nodeType) {
case XMLReader::END_ELEMENT: return $assoc;
case XMLReader::ELEMENT:
$name = $xml->name;
$atr = array();
if($xml->hasAttributes) while($xml->moveToNextAttribute()) $atr[$xml->name] = $xml->value;
$assoc[$name][] = array('name' => $name, 'attributes' => $atr, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
break;
case XMLReader::TEXT:
case XMLReader::CDATA: $assoc .= $xml->value;
}
}
return $assoc;
}
16-May-2008 05:09
Next version xml2assoc (real assoc):
function xml2assoc(&$xml) {
$assoc = NULL;
while($xml->read()){
switch ($xml->nodeType) {
case XMLReader::END_ELEMENT: return $assoc;
case XMLReader::ELEMENT:
$atr = array();
if($xml->hasAttributes) while($xml->moveToNextAttribute()) $atr[$xml->name] = $xml->value;
$assoc[$xml->name][] = array('name' => $xml->name, 'attributes' => $atr, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
break;
case XMLReader::TEXT:
case XMLReader::CDATA: $assoc .= $xml->value;
}
}
return $assoc;
}
03-Apr-2008 09:07
This is my solution for parsing XML file containing hierarchical menu of the web site that you can see below. Many thanks to Ariel Gonzalez for the implementation of DumpXmlReader() -- it was very helpful during debugging phase.
// XML file containing the menu
<?xml version="1.0" encoding="UTF-8"?>
<menu>
<!-- main page ======================================================== -->
<menu_item
title="Home"
page="main.html"
default="yes"> <!-- any value other than "yes" as well as no value at all means it's not the default page!!! -->
</menu_item>
<!-- news page ======================================================== -->
<menu_item
title="News"
page="news.html">
</menu_item>
<!-- company information ======================================================== -->
<menu_item
title="О компании"
page="about_company.html">
<menu_item
title="Who we are"
page="who_we_are.html">
</menu_item>
<menu_item
title="Our customers"
page="our_customers.html">
</menu_item>
<menu_item
title="Testimonials"
page="testimonials.html">
</menu_item>
</menu_item>
<!-- few pages skipped ======================================================== -->
<!-- Products page ======================================================== -->
<menu_item
title="Products"
page="products.html">
</menu_item>
<!-- Contacts page ======================================================== -->
<menu_item
title="Contacts"
page="contacts.html">
</menu_item>
</menu>
// PHP code
<?php
class menuItem
{
function menuItem($newTitle, $newPage, $newFolder = "", $newDefault = false, array $newSubMenu = NULL)
{
$this->title = $newTitle;
$this->page = $newPage;
$this->folder = $newFolder;
$this->default = $newDefault;
if( NULL != $newSubMenu )
{
$this->subMenu = $newSubMenu;
}
}
var $title = "";
var $page = "";
var $default = false;
var $folder = "";
var $subMenu = array();
}
function parseMenuFile($menuXmlFileName)
{
$xml = new XMLReader();
$xml->open($menuXmlFileName);
$menuRoot = new menuItem("", "");
parseXML($xml, $menuRoot);
// for debugging
DumpMenu($menuRoot->subMenu);
return $menuRoot->subMenu;
}
function DumpMenu(array &$menuItems)
{
foreach( $menuItems as $key=>$value )
{
echo( '<a href="index.php?page=' . $value->page . '">' . $value->title . '</a><br>' );
DumpMenu($value->subMenu);
}
}
// $XmlNode -- XMLReader pointing to the beginning of the next node in the XML file
// $baseMenuItem -- menu node whose sumbenu is to be filled with elements
function parseXML(XMLReader $XmlNode, &$baseMenuItem)
{
do
{
do
{
do
{
if( ! $XmlNode->read() )
{
return;
}
}
while( ! ( ($XmlNode->nodeType == XMLReader::ELEMENT) || ($XmlNode->nodeType == XMLReader::END_ELEMENT) ) );
}
while( $XmlNode->name != "menu_item" );
if( $XmlNode->nodeType == XMLReader::END_ELEMENT )
{
return;
}
$page = (string)$XmlNode->getAttribute("page");
$title = (string)$XmlNode->getAttribute("title");
$folder = (string)$XmlNode->getAttribute("folder");
$default = false;
if( "yes" == (string)$XmlNode->getAttribute("default") )
{
$default = true;
}
// valid menu item must have at least title and reference
// (url of the target content page) defined
if( ("" == $page) || ("" == $title) )
{
$title = "Error! No url or no title specified!";
}
$newItem = new menuItem($title, $page, $folder, $default, NULL);
$baseMenuItem->subMenu[] = $newItem;
//Call the recursive method again.
parseXML($XmlNode, $newItem);
}
while( true );
}
?>
16-Mar-2008 11:03
make some modify from Sergey Aikinkulov's note
function xml2assoc(&$xml){
$assoc = NULL;
$n = 0;
while($xml->read()){
if($xml->nodeType == XMLReader::END_ELEMENT) break;
if($xml->nodeType == XMLReader::ELEMENT and !$xml->isEmptyElement){
$assoc[$n]['name'] = $xml->name;
if($xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
$assoc[$n]['val'] = xml2assoc($xml);
$n++;
}
else if($xml->isEmptyElement){
$assoc[$n]['name'] = $xml->name;
if($xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
$assoc[$n]['val'] = "";
$n++;
}
else if($xml->nodeType == XMLReader::TEXT) $assoc = $xml->value;
}
return $assoc;
}
add else if($xml->isEmptyElement)
may be some xml has emptyelement
03-Mar-2008 11:22
<?php
/*
Read XML structure to associative array
--
Using:
$xml = new XMLReader();
$xml->open([XML file]);
$assoc = xml2assoc($xml);
$xml->close();
*/
function xml2assoc(&$xml){
$assoc = NULL;
$n = 0;
while($xml->read()){
if($xml->nodeType == XMLReader::END_ELEMENT) break;
if($xml->nodeType == XMLReader::ELEMENT){
$assoc[$n]['name'] = $xml->name;
if($xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
$assoc[$n]['val'] = xml2assoc($xml);
$n++;
}
else if($xml->nodeType == XMLReader::TEXT) $assoc = $xml->value;
}
return $assoc;
}
?>
20-Feb-2008 09:22
Matt,
Your recursive function to convert a multi-level XML file into an unordered list is great, but it has a flaw. The HTML it generates is not valid. This is how your function currently writes the HTML markup.
<ul>
<li></li>
<ul>
<li></li>
<ul>
<li></li>
</ul>
</ul>
</ul>
However, valid HTML dictates that when you nest a list inside another list, you must close the list inside the list item.
Here is valid HTML markup for a nested list:
<ul>
<li>
<ul>
<li></li>
</ul>
</li> <!-- nested list must be closed inside list item -->
</ul>
I have tweaked your recursive function so that it writes valid HTML when writing nested lists.
left_nav.xml:
<root>
<item name="Contact Information" url="some_url" />
<item name="Directions" url="some_url" />
<item name="Map" url="some_url" />
<item name="Links of Interest">
<item name="Labs/Centers/ Institutes" url="some_url" />
<item name="Journals/Societies" url="some_url" />
<item name="Other">
<item name="Brain Imaging" url="some_url" />
<item name="ASL" url="some_url" />
<item name="Miscellaneous" url="some_url" />
</item>
</item>
<item name="Gallery" url="some_url" />
</root>
<?php
$xml = new XMLReader();
$xml->open("left_nav.xml");
parseXML($xml);
function parseXML($node)
{
if (!$node->read())
return;
//If this is the root node, then just continue down the tree.
if ($node->nodeType==XMLReader::ELEMENT && $node->value == "root")
parseXML($node);
//If this is a text node then test for attributes.
if ($node->nodeType==XMLReader::ELEMENT && $node->hasAttributes)
{
if ($node->getAttribute("url") != "")
{
print "<li>";
print "<a href=\"" . $node->getAttribute("url") . "\">" . $node->getAttribute("name") . "</a>";
if ($node->isEmptyElement) {
print "</li>"; //only prints closing list tag if item does not have children
}
print "\n";
}
else
{
print "<li>";
print $node->getAttribute("name");
if ($node->isEmptyElement) {
print "</li>"; //only prints closing list tag if item does not have children
}
print "\n";
}
}
//If it is the beginning node then start the list.
if ($node->nodeType==XMLReader::ELEMENT && !$node->isEmptyElement)
print "<ul>\n";
//If it is the end node then close the list.
if ($node->nodeType==XMLReader::END_ELEMENT)
{
print "</ul>\n";
if ($node->name == "item") { print "</li>\n"; } //prints closing list tag for item that has children
}
//Call the recursive method again.
parseXML($node);
}
?>
15-Feb-2008 08:30
<?php
function parseXML($node,$seq,$path) {
global $oldpath;
if (!$node->read())
return;
if ($node->nodeType != 15) {
print '<br/>'.$node->depth;
print '-'.$seq++;
print ' '.$path.'/'.($node->nodeType==3?'text() = ':$node->name);
print $node->value;
if ($node->hasAttributes) {
print ' [hasAttributes: ';
while ($node->moveToNextAttribute()) print '@'.$node->name.' = '.$node->value.' ';
print ']';
}
if ($node->nodeType == 1) {
$oldpath=$path;
$path.='/'.$node->name;
}
parseXML($node,$seq,$path);
}
else parseXML($node,$seq,$oldpath);
}
$source = "<tag1>this<tag2 id='4' name='foo'>is</tag2>a<tag2 id='5'>common</tag2>record</tag1>";
$xml = new XMLReader();
$xml->XML($source);
print htmlspecialchars($source).'<br/>';
parseXML($xml,0,'');
?>
Output:
<tag1>this<tag2 id='4' name='foo'>is</tag2>a<tag2 id='5'>common</tag2>record</tag1>
0-0 /tag1
1-1 /tag1/text() = this
1-2 /tag1/tag2 [hasAttributes: @id = 4 @name = foo ]
2-3 /tag1/text() = is
1-4 /text() = a
1-5 /tag2 [hasAttributes: @id = 5 ]
2-6 /text() = common
1-7 /text() = record
30-Dec-2007 01:33
Here is an example of a recursive function to convert a multi-level XML file into an unordered list.
left_nav.xml:
<root>
<item name="Contact Information" url="some_url" />
<item name="Directions" url="some_url" />
<item name="Map" url="some_url" />
<item name="Links of Interest">
<item name="Labs/Centers/ Institutes" url="some_url" />
<item name="Journals/Societies" url="some_url" />
<item name="Other">
<item name="Brain Imaging" url="some_url" />
<item name="ASL" url="some_url" />
<item name="Miscellaneous" url="some_url" />
</item>
</item>
<item name="Gallery" url="some_url" />
</root>
<?php
$xml = new XMLReader();
$xml->open("left_nav.xml");
parseXML($xml);
function parseXML($node)
{
if (!$node->read())
return;
//If this is the root node, then just continue down the tree.
if ($node->nodeType==1 && $node->value == "root")
parseXML($node);
//If this is a text node then test for attributes.
if ($node->nodeType==1 && $node->hasAttributes)
{
if ($node->getAttribute("url") != "")
{
print "<li>";
print "<a href=\"" . $node->getAttribute("url") . "\">" . $node->getAttribute("name") . "</a>";
print "</li>\n";
}
else
{
print "<li>";
print $node->getAttribute("name");
print "</li>\n";
}
}
//If it is the beginning node then start the list.
if ($node->nodeType==1 && !$node->isEmptyElement)
print "<ul>\n";
//If it is the end node then close the list.
if ($node->nodeType==15)
print "</ul>\n";
//Call the recursive method again.
parseXML($node);
}
?>
14-Jul-2007 04:19
I found it a little hard to parse nested elements, so wrote a function simplifies it (based off http://www.thescripts.com/forum/thread627281.html):
<?php
function read_mixed_xml($filename, $arrayBeginElem, $arrayEndElem)
{
$output = "";
$arrayBeginKeys = array_keys($arrayBeginElem);
$lengthBegin = count($arrayBeginElem); // Length of the begin array
$arrayEndKeys = array_keys($arrayEndElem);
$lengthEnd = count($arrayEndElem); // Length of end element array
$xmlReader = new XMLReader();
$xmlReader->open($filename);
$xmlReader->read(); // Skip root node
/* Go through the nodes */
while($xmlReader->read())
{
/* We're only parsing begin and #text nodes right now */
if($xmlReader->nodeType != XMLReader::END_ELEMENT)
{
switch($xmlReader->nodeType)
{
/* If the current node is a begin element, go through the array of begin elements, in search of the current node's name. If it is, append $arrayBeginElem's value for the current node's name to the $output. (Simulates case "paragraph":
$output .= "<p>"
break;
) */
case XMLReader::ELEMENT:
for($i = 0; $i < $lengthBegin; $i++)
{
$key = $arrayBeginKeys[i];
if($key==$xmlReader->name)
{
$output .= $arrayBeginElem[$key];
}
}
break;
/* If the current node is a #text node, append the node's value to $output */
case XMLReader::TEXT:
$output .= $xmlReader->value;
break;
}
}
/* If the current node is an end element, go through the array of end elements, and search for the current node's name. If found, append $arrayEndElem's value for the current node's name to the output */
else if($xmlReader->nodeType == XMLReader::END_ELEMENT)
{
for($i = 0; $i < $lengthEnd; $i++)
{
$key = $arrayEndKeys[i];
if($key==$xmlReader->name)
{
$output .= $arrayEndElem[$key];
}
}
}
}
$xmlReader->close();
return $output;
}
Example input:
$begin = array("title" => " <h1>", "paragraph" => " <p>", "italicized" => "<i>");
$end = array("title" => "</h1>", "paragraph" => "</p>", "italicized" => "</i>");
$content = read_mixed_xml("index.xml", $begin, $end);
echo $content;
?>
index.xml:
<?xml version="1.0"?>
<body>
<title>Introduction</title>
<paragraph>
Lorem <italicized>ipsum dolor sit amet</italicized>, consectetuer adipiscing elit. Donec neque augue, nonummy sit amet, interdum vitae, egestas a, nulla. Aenean sed turpis eget lacus venenatis tincidunt. Integer in leo vitae est euismod congue. Curabitur quis tellus ut nulla pharetra fringilla. Phasellus id risus sagittis turpis lobortis pretium.
</paragraph>
<paragraph>
Curabitur ultrices pulvinar massa. Nullam ac massa. Morbi adipiscing pharetra est. In non neque vitae massa adipiscing vestibulum. Integer congue, lacus non sagittis consectetuer, magna nisl eleifend nisl, id fringilla justo justo et arcu.
</paragraph>
</body>
Example output:
<h1>Introduction</h1> <p>
Lorem <i>ipsum dolor sit amet</i>, consectetuer adipiscing elit. Donec neque augue, nonummy sit amet, interdum vitae, egestas a, nulla. Aenean sed turpis eget lacus venenatis tincidunt. Integer in leo vitae est euismod congue. Curabitur quis tellus ut nulla pharetra fringilla. Phasellus id risus sagittis turpis lobortis pretium.
</p> <p>
Curabitur ultrices pulvinar massa. Nullam ac massa. Morbi adipiscing pharetra est. In non neque vitae massa adipiscing vestibulum. Integer congue, lacus non sagittis consectetuer, magna nisl eleifend nisl, id fringilla justo justo et arcu.
</p>
14-Nov-2006 08:09
Example, as requested, with nested nodes.
<?php
ob_start();
?>
<root>
<folder>
<name>folder A</name>
<files>
<file>
<name>Afile 1</name>
</file>
<file>
<name>Afile 2</name>
</file>
</files>
</folder>
<folder>
<name>folder B</name>
<files>
<file>
<name>Bfile 1</name>
</file>
<file>
<name>Bfile 2</name>
</file>
</files>
</folder>
</root>
<?php
$xmldata = ob_get_contents();
ob_end_clean();
$xml = new XMLReader();
$xml->XML($xmldata);
$data = array();
while ($xml->read())
{
while($xml->depth<=2 && $xml->nodeType==1)
$xml->read();
if ($xml->nodeType==3 && $xml->depth==3) // NodeType 3 : Text Element
{
$strFolderName = $xml->value;
$data[$strFolderName]=array();
while($xml->depth<=3)
$xml->read();
while($xml->depth>=3)
{
//xdump();
if ($xml->nodeType==3)
$data[$strFolderName][] = $xml->value;
$xml->read();
}
}
}
print_r($data);
echo "\n";
?>
Output :
Array
(
[folder A] => Array
(
[0] => Afile 1
[1] => Afile 2
)
[folder B] => Array
(
[0] => Bfile 1
[1] => Bfile 2
)
)
20-Mar-2006 11:52
DTD Validation
Parser properties can be set using:
$xml_reader->setParserProperty(XMLReader::CONSTANT_NAME, BoolenValue);
The constant setting in the xmlreader_validatedtd.php example that comes
with the xmlread package results in an error.
Here is how I got it to work...
<?php
$indent = 5; /* Number of spaces to indent per level */
$xml = new XMLReader();
$xml->open("dtdexample.xml");
// CHANGED NEXT TWO LINES TO REMOVE ERROR
// FROM: $xml->setParserProperty(XMLREADER_LOADDTD, TRUE);
$xml->setParserProperty(XMLReader::LOADDTD, TRUE);
$xml->setParserProperty(XMLReader::VALIDATE, TRUE);
while($xml->read()) {
/* Print node name indenting it based on depth and $indent var */
print str_repeat(" ", $xml->depth * $indent).$xml->name."\n";
if ($xml->hasAttributes) {
$attCount = $xml->attributeCount;
print str_repeat(" ", $xml->depth * $indent)." Number of Attributes: ".$xml->attributeCount."\n";
}
}
print "\n\nValid:\n";
var_dump($xml->isValid());
?>
15-Feb-2006 04:50
Some more documentation (i.e. examples) would be nice :-)
This is how I read some mysql parameters in an xml file:
<?php
$xml = new XMLReader();
$xml->open("config.xml");
$xml->setParserProperty(2,true); // This seems a little unclear to me - but it worked :)
while ($xml->read()) {
switch ($xml->name) {
case "mysql_host":
$xml->read();
$conf["mysql_host"] = $xml->value;
$xml->read();
break;
case "mysql_username":
$xml->read();
$conf["mysql_user"] = $xml->value;
$xml->read();
break;
case "mysql_password":
$xml->read();
$conf["mysql_pass"] = $xml->value;
$xml->read();
break;
case "mysql_database":
$xml->read();
$conf["mysql_db"] = $xml->value;
$xml->read();
break;
}
}
$xml->close();
?>
The XML file used:
<?xml version='1.0'?>
<MySQL_INIT>
<mysql_host>localhost</mysql_host>
<mysql_database>db_database</mysql_database>
<mysql_username>root</mysql_username>
<mysql_password>password</mysql_password>
</MySQL_INIT>
11-Feb-2006 02:09
Simple function I used while playing around with XMLReader.
<?php
function dump_xmlreader($o) {
$node_types = array (
0=>"No node type",
1=>"Start element",
2=>"Attribute node",
3=>"Text node",
4=>"CDATA node",
5=>"Entity Reference node",
6=>"Entity Declaration node",
7=>"Processing Instruction node",
8=>"Comment node",
9=>"Document node",
10=>"Document Type node",
11=>"Document Fragment node",
12=>"Notation node",
13=>"Whitespace node",
14=>"Significant Whitespace node",
15=>"End Element",
16=>"End Entity",
17=>"XML Declaration node"
);
echo "attributeCount = " . $o->