Source for file XML.php
Documentation is available at XML.php
* Copyright (c) 1997-2007, Andrew Nagy <asnagy@webitecture.org>,
* Olivier Guilyardi <olivier@samalyse.com>,
* Mark Wiesemann <wiesemann@php.net>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* CSV file id: $Id: XML.php 260315 2008-05-26 14:34:19Z olivierg $
* @version $Revision: 260315 $
* @package Structures_DataGrid_DataSource_XML
* @license http://opensource.org/licenses/bsd-license.php New BSD License
require_once 'Structures/DataGrid/DataSource/Array.php';
* This class is a DataSource driver for XML data. It accepts strings
* and filenames. An XPath expression can be specified to extract data
* rows from the given XML data.
* - path: (string) XPath used to extract the data rows. The default
* is "*", which means all children of the context
* - namespaces: (array) Pairs of prefix/uri to register for XPath
* - fieldAttribute: (string) Which attribute of the XML source should be used
* as column field name (only used if the XML source
* - labelAttribute: (string) Which attribute of the XML source should be used
* as column label (only used if 'generate_columns'
* is true and the XML source has attributes).
* @example bind-xml1.php Bind a simple XML string
* @example bind-xml2.php Bind a more complex XML string using XPath
* @example bind-atom.php Bind an Atom feed with XPath and namespace
* @package Structures_DataGrid_DataSource_XML
* @author Olivier Guilyardi <olivier@samalyse.com>
* @author Mark Wiesemann <wiesemann@php.net>
* @version $Revision: 260315 $
Structures_DataGrid_DataSource_Array
// TODO: use XML_Indexing package for reading (=> streaming support)
parent ::Structures_DataGrid_DataSource_Array ();
$this->_addDefaultOptions (
'fieldAttribute' => null ,
* @param string $xml XML string or filename/stream
* @param array $options Options as an associative array
* @return mixed true on success, PEAR_Error on failure
function bind($xml, $options = array ())
$this->setOptions ($options);
$this->doc = $this->_loadDocument ($xml);
if (PEAR ::isError ($this->doc)) {
if ($path = $this->_options['xpath']) {
$this->_options['path'] = " $path/*";
$nodes = $this->doc->xpath ($this->_options['path'],
$this->_options['namespaces']);
foreach ($nodes as $rowNode) {
$this->_ar[] = $this->_processRow ($rowNode);
if (!$this->_options['labels']) {
$this->_options['labels'] = $this->_extractLabels ($nodes);
if ($this->_ar && !$this->_options['fields']) {
$this->setOption ('fields', array_keys($this->_ar[0 ]));
* Load XML Document Model
* @param string $xml XML string or filename
* @return object Structures_DataGrid_DataSource_XMLDomWrapper (PHP5) or
* Structures_DataGrid_DataSource_XMLDomXmlWrapper (PHP4)
function _loadDocument ($xml)
$doc = new Structures_DataGrid_DataSource_XMLDomWrapper ();
$doc = new Structures_DataGrid_DataSource_XMLDomXmlWrapper ();
return PEAR ::raiseError ('DOM (PHP5) or DOM XML (PHP4) is required '.
? $doc->loadString ($xml) : $doc->loadFile ($xml);
return PEAR ::raiseError ('XML couldn\'t be read.');
* Extract a data row out of a row node
* @param object $node Row node
* @return array Fields and values
function _processRow ($rowNode)
foreach ($rowNode->childNodes () as $fieldNode) {
$this->_extractFields ($row, $fieldNode);
foreach ($rowNode->attributes () as $name => $value) {
$row[] = array ('field' => " attributes$name" , 'content' => $value);
foreach ($row as $item) {
if (isset ($indexes[$field])) {
if (isset ($item['content'])) {
$flat[" $field$i" ] = $item['content'];
if (isset ($item['attributes'])) {
foreach ($item['attributes'] as $name => $value) {
$flat[" $field{$i}attributes$name" ] = $value;
* Extract one or more data fields out of a field node
* @param array $row reference to serialized row data, to put the
* @param object $fieldNode DOM field node
function _extractFields (&$row, $fieldNode)
foreach ($fieldNode->childNodes () as $valueNode) {
$nodeType = $valueNode->nodeType ();
if (($nodeType == XML_CDATA_SECTION_NODE )
|| ($nodeType == XML_TEXT_NODE )) {
$content .= $valueNode->nodeValue ();
$content .= $this->doc->getXML ($valueNode);
$fieldName = $this->_getFieldName ($fieldNode);
$nodeName = $fieldNode->nodeName ();
if ($nodeName != $fieldName) {
$row[] = array ('field' => $fieldName, 'content' => $content);
$row[] = array ('field' => $nodeName,
'attributes' => $fieldNode->attributes ());
$row[] = array ('field' => $nodeName, 'content' => $content,
'attributes' => $fieldNode->attributes ());
* Determine the main field name of a field node
* @param object $fieldNode DOM field node
function _getFieldName ($fieldNode)
$nodeName = $fieldNode->nodeName ();
foreach ($fieldNode->attributes () as $name => $content) {
if ($name == $this->_options['fieldAttribute']) {
* @param array $nodes Array of row nodes
* @return array Fields and Labels
function _extractLabels ($nodes)
$labelAttr = $this->_options['labelAttribute'];
$fieldAttr = $this->_options['fieldAttribute'];
if (count($nodes) && $labelAttr) {
foreach ($nodes[0 ]->childNodes () as $fieldNode) {
if (($name = $fieldAttr) && $fieldNode->hasAttribute ($name)) {
$fieldName = $fieldNode->getAttribute ($name);
$fieldName = $fieldNode->nodeName ();
if ($fieldNode->hasAttribute ($labelAttr)) {
= $fieldNode->getAttribute ($labelAttr);
* XML Document Model core Wrapper
* @package Structures_DataGrid_DataSource_XML
* @author Olivier Guilyardi <olivier@samalyse.com>
class Structures_DataGrid_DataSource_XMLWrapper
* @param object $domObject DOM or DOM XML object
function Structures_DataGrid_DataSource_XMLWrapper ($domObject = null )
$this->object = $domObject;
* Decorate items of an iterable object
* @param array $mixed Array or Iterable DOM/DOM XML object
* @return array Array of wrapped items
function wrapArray ($object)
foreach ($object as $key => $value) {
$wrapped[$key] = new $class($value);
* XML Document Model DOM (PHP5) Wrapper
* @package Structures_DataGrid_DataSource_XML
* @author Olivier Guilyardi <olivier@samalyse.com>
class Structures_DataGrid_DataSource_XMLDomWrapper
extends Structures_DataGrid_DataSource_XMLWrapper
* @return bool true on success, false on failure
function loadString ($xml)
$this->object = new DOMDocument ();
$this->object->preserveWhiteSpace = false;
return $this->object->loadXML ($xml);
* @param string $filename
* @return bool true on success, false on failure
function loadFile ($filename)
$this->object = new DOMDocument ();
$this->object->preserveWhiteSpace = false;
return $this->object->load ($filename);
* Run an xpath query, registering namespaces
* @param string $query XPath query
* @param array $namespaces prefix/uri pairs
* @return array Nodes found
function xpath ($query, $namespaces)
$xpath = new DOMXPath ($this->object);
foreach ($namespaces as $prefix => $uri) {
$xpath->registerNamespace ($prefix, $uri);
return $this->wrapArray ($xpath->query ($query));
* @return array Child nodes
return $this->wrapArray ($this->object->childNodes );
* Dump a node into an XML string
* @param object $node Node to dump
return $this->object->saveXML ($node->object );
return $this->object->nodeName;
* Get all node's attributes
* @return array name/value pairs
foreach ($this->object->attributes as $item) {
$attributes[$item->name ] = $item->value;
* Check for attribute existence
function hasAttribute ($name)
return $this->object->hasAttribute ($name);
function getAttribute ($name)
return $this->object->getAttribute ($name);
return $this->object->nodeType;
return $this->object->nodeValue;
* XML Document Model DOM XML (PHP4) Wrapper
* @package Structures_DataGrid_DataSource_XML
* @author Olivier Guilyardi <olivier@samalyse.com>
class Structures_DataGrid_DataSource_XMLDomXmlWrapper
extends Structures_DataGrid_DataSource_XMLWrapper
* @return bool true on success, false on failure
function loadString ($xml)
$this->object = domxml_open_mem ($xml, DOMXML_LOAD_DONT_KEEP_BLANKS );
return (bool) $this->object;
* @param string $filename
* @return bool true on success, false on failure
function loadFile ($filename)
$this->object = domxml_open_file ($filename, DOMXML_LOAD_DONT_KEEP_BLANKS );
return (bool) $this->object;
* Run an xpath query, registering namespaces
* @param string $query XPath query
* @param array $namespaces prefix/uri pairs
* @return array Nodes found
function xpath ($query, $namespaces)
$xpath = xpath_new_context ($this->object);
foreach ($namespaces as $prefix => $uri) {
xpath_register_ns ($xpath, $prefix, $uri);
$result = xpath_eval ($xpath, $query);
return $this->wrapArray ($result->nodeset );
* @return array Child nodes
return $this->wrapArray ($this->object->child_nodes ());
* Dump a node into an XML string
* @param object $node Node to dump
return $this->object->dump_node ($node->object );
return $this->object->node_name ();
* Get all node's attributes
* @return array name/value pairs
if ($items = $this->object->attributes ()) {
foreach ($items as $item) {
$attributes[$item->name ()] = $item->value ();
* Check for attribute existence
function hasAttribute ($name)
return $this->object->has_attribute ($name);
function getAttribute ($name)
return $this->object->get_attribute ($name);
return $this->object->node_type ();
return $this->object->node_value ();
/* vim: set expandtab tabstop=4 shiftwidth=4: */
Documentation generated on Sun, 10 Oct 2010 13:30:03 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.
|