Files
IPB/upload/ips_kernel/class_xml.php
T
2025-12-19 00:19:56 -08:00

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", '&amp;', $t );
$t = str_replace( "<", "&lt;" , $t );
$t = str_replace( ">", "&gt;" , $t );
$t = str_replace( '"', "&quot;", $t );
$t = str_replace( "'", '&#039;', $t );
return $t;
}
/*-------------------------------------------------------------------------*/
// INTERNAL: Encodes an attribute string
/*-------------------------------------------------------------------------*/
function _xml_decode_attribute( $t )
{
$t = str_replace( "&amp;" , "&", $t );
$t = str_replace( "&lt;" , "<", $t );
$t = str_replace( "&gt;" , ">", $t );
$t = str_replace( "&quot;", '"', $t );
$t = str_replace( "&#039;", "'", $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;
}
}
?>