400 lines
11 KiB
PHP
400 lines
11 KiB
PHP
<?php
|
|
|
|
/*
|
|
+--------------------------------------------------------------------------
|
|
| Invision Power Board v2.0.0
|
|
| =============================================
|
|
| by Matthew Mecham
|
|
| (c) 2001 - 2004 Invision Power Services, Inc.
|
|
| http://www.invisionpower.com
|
|
| =============================================
|
|
| Web: http://www.invisionboard.com
|
|
| Time: Tue, 21 Sep 2004 16:34:28 GMT
|
|
| Release: 150aa7a702c3c8b6f6eb90ad49305d2f
|
|
| Licence Info: http://www.invisionboard.com/?license
|
|
+---------------------------------------------------------------------------
|
|
|
|
|
| > XML handling methods (KERNEL)
|
|
| > Module written by Matt Mecham
|
|
| > Date started: 25th February
|
|
|
|
|
| > Module Version Number: 1.0.0
|
|
+--------------------------------------------------------------------------
|
|
|
|
<productlist name="myname" version="1.0">
|
|
<productgroup name="thisgroup">
|
|
<product id="1.0">
|
|
<description>This is a descrption</description>
|
|
<title>Baked Beans</title>
|
|
<room store="1">103</room>
|
|
</product>
|
|
</productgroup>
|
|
</productlist>
|
|
|
|
# Set the root tag
|
|
$xml->xml_set_root( 'productlist', array( 'name' => 'myname', 'version' => '1.0' ) );
|
|
|
|
# Add a group
|
|
$xml->xml_add_group( 'productgroup', array( 'name' => 'thisgroup' ) );
|
|
|
|
# Build entry content
|
|
$content[] = $xml->xml_build_simple_tag( 'description', "This is a descrption" );
|
|
$content[] = $xml->xml_build_simple_tag( 'title' , "Baked Beans" );
|
|
$content[] = $xml->xml_build_simple_tag( 'room' , '103' , array( 'store' => 1 ) );
|
|
|
|
# Build entry
|
|
$entry[] = $xml->xml_build_entry( 'product', $content, array( 'id' => '1.0' ) );
|
|
|
|
# Add to group 'productlist'
|
|
$xml->xml_add_entry_to_group( 'productgroup', $entry );
|
|
|
|
# Format..
|
|
$xml->xml_format_document();
|
|
|
|
# Get XML document
|
|
$filecontents = $xml->xml_document;
|
|
|
|
# Parse XML document
|
|
$xml->xml_parse_document( $filecontents );
|
|
|
|
# Show XML array
|
|
print_r( $xml->xml_array );
|
|
|
|
# print "Baked Beans";
|
|
print $xml->xml_array['productlist']['productgroup']['product'][0]['title']['VALUE'];
|
|
|
|
# print "1";
|
|
print $xml->xml_array['productlist']['productgroup']['product'][0]['room']['ATTRIBUTES']['store'];
|
|
|
|
*/
|
|
|
|
|
|
class class_xml
|
|
{
|
|
var $header = '<?xml version="1.0" encoding="ISO-8859-1"?>';
|
|
var $root_tag = '';
|
|
var $root_attributes = "";
|
|
var $entries = array();
|
|
var $xml_document = "";
|
|
var $depth = 0;
|
|
var $tmp_doc = "";
|
|
var $groups = "";
|
|
var $index_numeric = 0;
|
|
var $collapse_dups = 1;
|
|
var $xml_array = array();
|
|
var $collapse_newlines = 1;
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// CONSTRUCTOR
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function class_xml()
|
|
{
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Parse an XML document into arrays
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_parse_document( $xml )
|
|
{
|
|
$parser = xml_parser_create();
|
|
|
|
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
|
|
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE , 0);
|
|
xml_parse_into_struct($parser, $xml, $vals, $index);
|
|
xml_parser_free($parser);
|
|
|
|
$i = -1;
|
|
|
|
$this->xml_array = $this->_xml_get_children($vals, $i);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Format the XML document
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_format_document( $entry=array() )
|
|
{
|
|
$this->xml_document = $this->header ? $this->header."\n" : '';
|
|
|
|
$this->xml_document .= "<".$this->root_tag.$this->root_attributes.">\n";
|
|
|
|
$this->xml_document .= $this->tmp_doc;
|
|
|
|
$this->xml_document .= "\n</".$this->root_tag.">";
|
|
|
|
$this->tmp_doc = "";
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Set the root tags
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_set_root($tag, $attributes=array() )
|
|
{
|
|
$this->root_tag = $tag;
|
|
$this->root_attributes = $this->_xml_build_attribute_string( $attributes );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Add entries to the group
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_add_entry_to_group($tag, $entry=array() )
|
|
{
|
|
$this->tmp_doc .= "\t".$this->groups[ $tag ];
|
|
|
|
if ( is_array( $entry ) and count( $entry ) )
|
|
{
|
|
foreach( $entry as $e )
|
|
{
|
|
$this->tmp_doc .= "\n\t\t".$e."\n";
|
|
}
|
|
}
|
|
|
|
$this->tmp_doc .= "\t</".$tag.">\n";
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Builds an entry
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_build_entry( $tag, $content=array(), $attributes=array() )
|
|
{
|
|
$entry = "<" . $tag . $this->_xml_build_attribute_string($attributes) . ">\n";
|
|
|
|
if ( is_array( $content ) and count( $content ) )
|
|
{
|
|
foreach( $content as $c )
|
|
{
|
|
$entry .= "\t\t\t".$c."\n";
|
|
}
|
|
}
|
|
|
|
$entry .= "\t\t</" . $tag . ">";
|
|
|
|
return $entry;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Add a group
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_add_group( $tag, $attributes=array() )
|
|
{
|
|
$this->groups[ $tag ] = "<" . $tag . $this->_xml_build_attribute_string($attributes) . ">";
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// Builds a simple <tag [key="value"]>content</tag> structure
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function xml_build_simple_tag( $tag, $description="", $attributes=array() )
|
|
{
|
|
return "<" . $tag . $this->_xml_build_attribute_string($attributes) . ">" . $this->_xml_encode_string($description) . "</" . $tag . ">";
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Build tree node
|
|
// Based on code found at http://php.net/manual/en/function.xml-parse-into-struct.php
|
|
// And http://eric.pollmann.net/work/public_domain/
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_build_tag( $thisvals, $vals, &$i, $type )
|
|
{
|
|
$tag = array();
|
|
|
|
if ( isset($thisvals['attributes']) )
|
|
{
|
|
$tag['ATTRIBUTES'] = $this->_xml_decode_attribute($thisvals['attributes']);
|
|
}
|
|
|
|
if ( $type === 'complete' )
|
|
{
|
|
$tag['VALUE'] = $thisvals['value'];
|
|
}
|
|
else
|
|
{
|
|
$tag = array_merge( $tag, $this->_xml_get_children($vals, $i) );
|
|
}
|
|
|
|
return $tag;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Build a nested array of children
|
|
// Based on code found at http://php.net/manual/en/function.xml-parse-into-struct.php
|
|
// And http://eric.pollmann.net/work/public_domain/
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_get_children($vals, &$i)
|
|
{
|
|
$children = array();
|
|
|
|
//-----------------------------------
|
|
// CDATA before children
|
|
//-----------------------------------
|
|
|
|
if ( $i > -1 && isset( $vals[$i]['value'] ) )
|
|
{
|
|
$children['VALUE'] = $vals[$i]['value'];
|
|
}
|
|
|
|
//-----------------------------------
|
|
// Loopy loo
|
|
//-----------------------------------
|
|
|
|
while( ++$i < count( $vals ) )
|
|
{
|
|
$type = $vals[$i]['type'];
|
|
|
|
//-----------------------------------
|
|
// CDATA after children
|
|
//-----------------------------------
|
|
|
|
if ($type === 'cdata')
|
|
{
|
|
$children['VALUE'] .= $vals[$i]['value'];
|
|
}
|
|
|
|
//-----------------------------------
|
|
// COMPLETE: At end of current branch
|
|
// OPEN: Node has children, recurse
|
|
//-----------------------------------
|
|
|
|
else if ( $type === 'complete' OR $type === 'open' )
|
|
{
|
|
$tag = $this->_xml_build_tag( $vals[$i], $vals, $i, $type );
|
|
|
|
if ( $this->index_numeric )
|
|
{
|
|
$tag['TAG'] = $vals[$i]['tag'];
|
|
$children[] = $tag;
|
|
}
|
|
else
|
|
{
|
|
$children[$vals[$i]['tag']][] = $tag;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------
|
|
// End of node?
|
|
//-----------------------------------
|
|
|
|
else if ($type === 'close')
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( $this->collapse_dups )
|
|
{
|
|
foreach( $children as $key => $value )
|
|
{
|
|
if ( is_array($value) && (count($value) == 1) )
|
|
{
|
|
$children[$key] = $value[0];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $children;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Builds attribute string
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_build_attribute_string( $array = array() )
|
|
{
|
|
if ( is_array( $array ) and count( $array ) )
|
|
{
|
|
$string = array();
|
|
|
|
foreach( $array as $k => $v )
|
|
{
|
|
$v = trim( $this->_xml_encode_attribute($v) );
|
|
|
|
$string[] = $k.'="'.$v.'"';
|
|
}
|
|
|
|
return ' ' . implode( " ", $string );
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Encodes an attribute string
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_encode_attribute( $t )
|
|
{
|
|
$t = preg_replace("/&(?!#[0-9]+;)/s", '&', $t );
|
|
$t = str_replace( "<", "<" , $t );
|
|
$t = str_replace( ">", ">" , $t );
|
|
$t = str_replace( '"', """, $t );
|
|
$t = str_replace( "'", ''', $t );
|
|
|
|
return $t;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Encodes an attribute string
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_decode_attribute( $t )
|
|
{
|
|
$t = str_replace( "&" , "&", $t );
|
|
$t = str_replace( "<" , "<", $t );
|
|
$t = str_replace( ">" , ">", $t );
|
|
$t = str_replace( """, '"', $t );
|
|
$t = str_replace( "'", "'", $t );
|
|
|
|
return $t;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Encodes a string to make it safe (uses cdata)
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_encode_string( $v )
|
|
{
|
|
if ( preg_match( "/['\"\[\]<>&]/", $v ) )
|
|
{
|
|
$v = "<![CDATA[" . $this->_xml_convert_safecdata($v) . "]]>";
|
|
}
|
|
|
|
if ( $this->collapse_newlines )
|
|
{
|
|
$v = str_replace( "\r\n", "\n", $v );
|
|
}
|
|
|
|
return $v;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Ensures no embedding of cdata
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_convert_safecdata( $v )
|
|
{
|
|
$v = str_replace( "<![CDATA[", "<!¢|CDATA|", $v );
|
|
$v = str_replace( "]]>" , "|¢]>" , $v );
|
|
return $v;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
// INTERNAL: Uncoverts safe embedding
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
function _xml_unconvert_safecdata( $v )
|
|
{
|
|
$v = str_replace( "<!¢|CDATA|", "<![CDATA[", $v );
|
|
$v = str_replace( "|¢]>" , "]]>" , $v );
|
|
return $v;
|
|
}
|
|
|
|
}
|
|
|
|
?>
|