;?
Class Arraytree
{
private $stack;
private $tree;
private $location;
Private $locationstring;
public function __construct ($tree = False)
{ $this->stack = Array (); br> if ($tree)
$this->tree = $tree;
else
$ This->tree = Array ();
$this->location = 0;
public function Startbranch ()
{ $this->location++
$this->stack[] = $this->location;
$this->location = 0;
$this->nodes = 0;
$this->locationstring = "";
foreach ($this->stack as $v)
$this->locationstring. = "[' Node: $v ']";
Eval (' $this->tree '.) $this->locationstring = Array (); ");
Eval (' $this->tree '.) $this->locationstring "." [' nodes '] = 0; ");
}
Public Function Addleaf ($name, $value)
{$name = Htmlspecialchars ($name, ent_quotes);
if (Is_array ($value) && sizeof ($value) > 0)
{$arr = "Array (";
foreach ($value as $n => $v)
{$v = addslashes ("$v");
$arr. = "' $n ' => ' $v ',";
}
$arr. = "' $n ' => ' $v ')";
Echo ' $this->tree '. $this->locationstring "." [' $name '] "." = $arr; ";
Eval (' $this->tree '.) $this->locationstring "." [' $name '] "." = $arr; ");
}
Else
{
if (Is_array ($value) && sizeof ($value) = = 0)
$value = ';
$value = Htmlspecialchars ($value, ent_quotes);
$tmp = ' $this->tree '. $this->locationstring "." [' $name '] '. = "$value"; ";
Echo ($TMP);
eval ($tmp);
}
}
Public Function Endbranch ()
{
$this->location = Array_pop ($this->stack);
$this->locationstring = "";
foreach ($this->stack as $v)
$this->locationstring. = "[' Node: $v ']";
Eval (' $this->tree '.) $this->locationstring "." [' nodes '] = $this->location; ");
}
Public Function Gettree ()
{return $this->tree;
}
}
/***************************************************
* * Xmlparser Object
* * Helper object for parsing XML in Arraytree
***************************************************/
Class Xmlparser
{
Private $filename;
Private $data;
Private $currentItem;
Private $didread;
Private $depth;
Private $deptharr;
Private $parsed;
Private $pointer;
Private $parser;
Private $p;
Private $arrayout;
Private $tree;
Public function __construct ($xml, $isfile = True)
{
if ($isfile)
{$file = $xml;
$this->filename = $file;
}
Else
{$this->data = $xml;
$this->filename = false;
}
$this->tree = new Arraytree;
$this->tree->addleaf (' nodes ', 0);
$this->depth = 0;
$this->deptharr = Array ();
$this->pointer = ' $this->parsed ';
$this->currentitem = Array ();
$this->didread = false;
$this->parsed = Array ();
$this->arrayout = "";
}
Public Function startelement ($parser, $name, $attrs)
{$this->parsed = "";
$this->tree->startbranch ();
$this->tree->addleaf (' name ', $name);
$this->tree->addleaf (' attributes ', $attrs);
}
Public Function Characterdata ($parser, $data)
{if (! $this->didread)
$this->parsed = $data;
Else
$this->parsed. = $data;
$this->didread = true;
}
Public Function EndElement ($parser, $name)
{$this->tree->addleaf (' value ', $this->parsed);
$this->parsed = "";
$this->tree->endbranch ();
}
Public Function Parse ()
{
$this->parser = Xml_parser_create ();
Xml_set_object ($this->parser, $this);
Xml_parser_set_option ($this->parser, xml_option_case_folding, false);
Xml_set_element_handler ($this->parser, "startelement", "endelement");
Xml_set_character_data_handler ($this->parser, "Characterdata");
if ($this->filename!== false)
{$data = file_get_contents ($this->filename);
if (! $data)
return false;
}
Else
$data = $this->data;
$data =eregi_replace (">"). [[: space:]]+ "." < "," >< ", $data);
$data =str_replace ("&", "&", $data);
if (!xml_parse ($this->parser, $data))
{ die (sprintf ("XML error:%s at line%d",
xml_error_ String (Xml_get_error_code ($this->parser)),
Xml_get_current_line_number ($this->parser));
}
xml_parser_free ($this->parser);
$data =str_replace ("&", "&", $this->tree->gettree ());
return $data [' node:1 '];
}
}
/***************************************************
* * Swiftxml Object
* * Allows user access to XML data stored
***************************************************/
Class Swiftxml implements Iteratoraggregate
{
Private $XMLtree;
Public function __construct (& $xml = False, $type = Xml_file)
{
if (Is_array ($xml) | | | $type = = xml_tree)
{$this->usearray ($xml);
}
else if ($type = = xml_file)
{$this->usefile ($xml);
}
else if ($type = = Xml_text)
{$this->usetext ($xml);
}
}
Public Function & __get ($x)
{
return $this->get ($x);
}
Public Function __set ($x, $y)
{
$this->set ($x, $y);
}
Public Function __call ($x, $y)
{if (array_key_exists ($x, $this->xmltree))
return $this->xmltree[$x];
Else
return false;
}
Public Function __tostring ()
{
return $this->xmltree[' value '];
}
iterator function
Public Function Getiterator ()
{return new Arrayiterator ($this->xmltree);
}
Initialize functions
Public Function Usefile ($file)
{$x = new Xmlparser ($file);
$this->xmltree = $x->parse ();
}
Public Function Usetext ($text)
{$x = new Xmlparser ($text, false);
$this->xmltree = $x->parse ();
}
Public Function Usearray (& $arr)
{$this->xmltree = $arr;
}
Return tree as XML
Public Function Asxml ($header = true, $tree = false, $depth = 0)
{if (! $tree)
$tree = $this->xmltree;
$output = "";
if ($header)
{
$output = "<?xml version=" 1.0 "encoding=" UTF-8 "?>";
}
$tabs = Str_repeat ("", $depth);
$output. = "$tabs < $tree [name]";
if ($tree [' Attributes ']!= "" && is_array ($tree [' Attributes '])
{foreach ($tree [' attributes '] as $n => $v)
$output. = "$n =" $v "";
}
$output. = "> $tree [value]";
if ($tree [' nodes '] > 0)
{foreach ($tree as $n => $v)
{if (substr ($n, 0,5) = = "Node:")
$output. = "". $this->asxml (False, $tree [$n], $depth + 1);
}
$output. = "$tabs";
}
$output. = "</$tree [name]>";
return $output;
}
Return XMLtree
Public Function Getdetailedtree ()
{return $this->xmltree;
}
Return a simplified tree as a array, where is the array keys correspond to XML tags
Public Function Getsimpletree ($showattribs = False, & $tree = False)
{if (! $tree)
$tree = $this->xmltree;
Tree has no branches
if (sizeof ($tree) < 5)
return $tree [' value '];
$output = Array ();
foreach ($tree as $n => $v)
{if (substr ($n, 0,5) = = ' node: ')
{$vname = $v [' name '];
$attribstr = "";
$vattrib = $v [' Attributes '];
if (Array_key_exists ($vname, $output))
{if (!is_array ($output [$vname]) | |!array_key_exists (0, $output [$vname]))
{$existingvalue = $output [$vname];
$existingvattrib = false;
if ($showattribs && array_key_exists ($vname.) /attributes ", $output))
$existingvattrib = $output [$vname.] /attributes "];
$output = Array ();
$output [$vname] = array ();
$output [$vname] = $existingvalue;
if ($showattribs && $existingvattrib)
$output [$vname] ["0/attributes"] = $existingvattrib;
}
$output [$vname] = $this->getsimpletree ($showattribs, $v);
if ($showattribs && Is_array ($vattrib))
$output [$vname][end (Array_keys ($output [$vname])). " /attributes "] = $vattrib;
}
Else
{
$output [$vname] = $this->getsimpletree ($showattribs, $v);
echo "--> $vname:". $output [$vname]. " ";
if ($showattribs && Is_array ($vattrib))
$output [$vname.] /attributes "]= $vattrib;
}
}
}
return $output;
}
$location takes the format "Block1/block2/block3"
Private Function & Getnodebylocation ($location, & $tree = False)
{if (! $tree)
$tree = & $this->xmltree;
$location = ereg_replace ("^/", "", $location);
$location = ereg_replace ("/$", "", $location);
if ($slashpos = Strpos ($location, "/"))
{$nodename = substr ($location, 0, $slashpos);
$rest = substr ($location, $slashpos +1,strlen ($location)-$slashpos + 1);
return $this->getnodebylocation ($rest, $this->getnodebyname ($tree, $nodename));
}
Else
return $this->getnodebyname ($tree, $location);
}
Public Function doesexist ($location)
{return getnodebylocation ($location) ==! false true:false;
}
Returns XML Object
Public Function & GetNode ($location)
{$tmp = $this->getnodebylocation ($location);
if ($tmp = = False)
return false;
Else
return new Swiftxml ($tmp, Xml_tree);
}
Accepts $newnode as XML object
Public Function Setnode ($newnode, $location)
{$locnode = & $this->getnodebylocation ($location);
Print_r ($locnode);
$locnode = $newnode->getdetailedtree ();
}
Public Function GetValue ($location)
{
$arr = $this->getnodebylocation ($location);
if ($arr!== false)
return $arr [' value '];
Else
return false;
}
Public Function SetValue ($value, $location = False)
{
if (! $location)
$arr = & $this->xmltree;
Else
$arr = & $this->getnodebylocation ($location);
$arr [' value '] = $value;
}
Public function set ($location, $value)
{
if (Is_array ($value))
$this->settree ($value, $location);
else if (is_a ($value, "Swiftxml"))
$this->setnode ($value, $location);
Else
$this->setvalue ($value, $location);
}
Public Function Settree ($value, $location = False)
{if (! $location)
$arr = & $this->xmltree;
Else
$arr = & $this->getnodebylocation ($location);
$arr = $value;
}
Public Function getattributes ($location)
{
$arr = $this->getnodebylocation ($location);
return $arr [' attributes '];
}
Public Function getattribute ($location, $attrib)
{
$arr = $this->getnodebylocation ($location);
if (Array_key_exists ($attrib, $arr [' Attributes '])
return $arr [' attributes '] [$attrib];
Else
return false;
}
Public Function setattribute ($attribname, $attribvalue, $location = False)
{if (! $location)
$arr = & $this->xmltree;
Else
$arr = & $this->getnodebylocation ($location);
if (!is_array ($arr [' Attributes '])
$arr [' attributes '] = array ();
$arr [' Attributes '] [$attribname] = $attribvalue;
}
Public Function SetAttributes ($arr, $location = False)
{if (! $location)
$arr 2 = & $this->xmltree;
Else
$arr 2 = & $this->getnodebylocation ($location);
$arr 2[' attributes '] = $arr;
}
Easiest way to get info from ' an XML document ' to ' use ' function get ()
Get () guesses what format to the data in based.
It'll return a array of XML objects if $location is ambiguous.
If one tag exists at $location, it would be returned and a XML object, unless it has no attributes,
In which case the value is returned as a string.
//
Use the prefix//to indicate a location wildcard (run Getnodearrayrecursize)
Public function Get ($location)
{
if (Ereg ("^//", $location) | | ereg ("^*/", $location))
return $this->getnodearrayrecursive (substr ($location, 2,strlen ($location)-2));
$output = $this->getnodearray ($location);
if ($output!== false && count ($output) = = 1)
{$tree = $output [0]->getdetailedtree ();
if ($tree [' nodes '] = = 0 &&!is_array ($tree [' Attributes '])
$output = $tree [' value '];
Else
$output = $output [0];
}
return $output;
}
Public Function Getnodearray ($location)
{
if (Ereg ("^//", $location) | | ereg ("^*/", $location))
return $this->getnodearrayrecursive (substr ($location, 2,strlen ($location)-2));
$output = Array ();
$lastpos = Strrpos ($location, "/");
if ($lastpos!== false)
{$subloc = substr ($location, 0, $lastpos);
$nodename = substr ($location, $lastpos +1,strlen ($location)-1);
$node = $this->getnode ($subloc);
if ($node = = False)
return false;
$tree = $node->getdetailedtree ();
}
Else
{$subloc = $location;
$nodename = $location;
$tree = $this->xmltree;
}
for ($i = 1; $i <= $tree [' nodes ']; $i + +)
{if ($tree [node: $i] [' name '] = = $nodename)
$output [] = Swiftxml_use_tree ($tree ["Node: $i"]);
}
if (count ($output) = 0)
return false;
Else
return $output;
}
Returns an array of ' any ' node named $location in $tree
Private Function Getnodearrayrecursive ($location, $tree = False)
{if (! $tree)
$tree = $this->xmltree;
$output = Array ();
if ($tree [' name '] = = $location)
$output [] = Swiftxml_use_tree ($tree);
for ($i = 1; $i <= $tree [' nodes ']; $i + +)
$output =array_merge ($output, $this->getnodearrayrecursive ($location, $tree ["Node: $i"]);
return $output;
}
Assistant function; Pulls a subarray from the $tree
Private Function & Getnodebyname (& $tree, $name, $debug = False)
{if ($debug) echo "Getnodebyname ($tree, $name);";
if (!is_array ($tree))
{if ($debug) echo ("[". $tree. "]");
return false;
}
foreach ($tree as $n => $v)
{if (Is_array ($v) and array_key_exists (' name ', $v))
{if ($debug) echo $tree [$n] [' name ']. "= = $name? ";
if ($v [' name '] = = $name)
return $tree [$n];
}
if ($debug) echo $n. " ";
}
return false;
}
Public Function Createchild ($name, $value = "", $attributes = "")
{
$nodes = + + $this->xmltree[' nodes '];
if (Is_a ($name, "Swiftxml"))
{$this->xmltree["node: $nodes"] = $name->getdetailedtree ();
$nodes = $this->xmltree[' nodes '];
}
Else
$this->xmltree["node: $nodes"] = Array ("name" => $name,
"Value" => $value,
"Attributes" => $attributes,
"Nodes" => 0);
return $nodes;
}
}
Define ("Xml_file", "FILE");
Define ("Xml_tree", "tree");
Define ("Xml_text", "TEXT");
Define ("Xml_no_curl", false);
Assistant functions for initializing XML objects
Function & Swiftxml_use_file ($filename, $use _curl = True)
{
if (Ereg ("://", $filename) && $use _curl && function_exists (' Curl_init '))
Return Swiftxml_use_curl ($filename);
Else
return new Swiftxml ($filename, xml_file);
}
Function & Swiftxml_use_text ($text)
{return new Swiftxml ($text, Xml_text);
}
Function & Swiftxml_use_tree ($tree)
{return new Swiftxml ($tree, Xml_tree);
}
Function & Swiftxml_use_curl ($filename)
{
$ch = Curl_init ();
curl_setopt ($ch, Curlopt_url, $filename);
curl_setopt ($ch, Curlopt_useragent, "swiftxml/1.1");
curl_setopt ($ch, Curlopt_returntransfer, true);
curl_setopt ($ch, Curlopt_header, 0);
$text = curl_exec ($ch);
Curl_close ($ch);
return new Swiftxml ($text, Xml_text);
}
Function & Swiftxml_create ($name, $value = "", $attributes = "")
{
return Swiftxml_use_tree (Array ("name" => $name,
"Value" => $value,
"Attributes" => $attributes,
"Nodes" => 0));
}
?>
Parsing an XML document
<body>
?
Include_once (' swiftxml.1.1.php tutorial ');
$XML = Swiftxml_use_file (' http://www.111cn.net tutorial/feed/rss2/');
echo "echo "
foreach ($XML->get ("//item") as $item)
{$url = $item->get ("link");
$title = $item->get ("title");
$desc = $item->get ("description");
Echo Html_entity_decode ("
}
?>
</body>
Create an XML document under
?
Include_once (' swiftxml.1.1.php ');
$rss = swiftxml_create ("RSS");
$rss->setattribute ("version", "2.0");
$channel = Swiftxml_create ("channel");
$channel->createchild ("title", "Swiftly tilting");
$channel->createchild ("link", "http://www.111cn.net");
for ($i = 0; $i < $i + +)
{$item = Swiftxml_create ("item");
$item->createchild ("title", "title $i");
$item->createchild ("description", "description $i");
$channel->createchild ($item);
}
$rss->createchild ($channel);
Header ("Content-type:text/xml");
echo $rss->asxml ();
?>