cvs: pear /XML_sql2xml package.xml sql2xml.php sql2xml_ext.php

From: Date: Thu, 16 Aug 2001 08:14:34 +0000
Subject: cvs: pear /XML_sql2xml package.xml sql2xml.php sql2xml_ext.php
Groups: php.pear.cvs 
Request: Send a blank email to pear-cvs+get-549@lists.php.net to get a copy of this message
chregu Thu Aug 16 04:14:34 2001 EDT Modified files: /pear/XML_sql2xml package.xml sql2xml.php sql2xml_ext.php Log: - it's possible to add an xml-file - it's possible to add an xml-string - a little bit more error-checking (not perfect... needs more adaption to pear standard) - changing in dom-xml syntax (to work with 4.0.6 and below) - functions in sql-queries are handled better - setOption can delete all previous options

Index: pear/XML_sql2xml/package.xml diff -u pear/XML_sql2xml/package.xml:1.1 pear/XML_sql2xml/package.xml:1.2 --- pear/XML_sql2xml/package.xml:1.1 Fri Aug 3 03:22:44 2001 +++ pear/XML_sql2xml/package.xml Thu Aug 16 04:14:34 2001 @@ -3,18 +3,20 @@ generated package.xml files --> <Package> <Name>XML_sql2xml</Name> - <Summary>This class takes a PEAR::DB-Result Object, a sql-query-string or an array and returns a xml-representation of it.</Summary> + <Summary>This class takes a PEAR::DB-Result Object, a sql-query-string, an array and/or an xml-string/file and returns a xml-representation of it.</Summary> <Maintainer> <Initials>cs</Initials> <Name>Christian Stocker</Name> <Email>chregu@php.net</Email> </Maintainer> <Release> - <Version>0.1</Version> - <Date>2001-08-03</Date> + <Version>0.2</Version> + <Date>2001-08-16</Date> <Notes> - Documentation is in the php-file itself. - API may change. + New Features: + - Adding of XML-files/strings is possible + - works with 4.0.6 and below + - setOption can delete values set before. </Notes> </Release> <FileList> Index: pear/XML_sql2xml/sql2xml.php diff -u pear/XML_sql2xml/sql2xml.php:1.1 pear/XML_sql2xml/sql2xml.php:1.2 --- pear/XML_sql2xml/sql2xml.php:1.1 Fri Aug 3 03:22:44 2001 +++ pear/XML_sql2xml/sql2xml.php Thu Aug 16 04:14:34 2001 @@ -12,10 +12,10 @@ // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ -// | Authors: Christian Stocker <chregu@nomad.ch> | +// | Authors: Christian Stocker <chregu@phant.ch> | // +----------------------------------------------------------------------+ // -// $Id: sql2xml.php,v 1.1 2001/08/03 07:22:44 chregu Exp $ +// $Id: sql2xml.php,v 1.2 2001/08/16 08:14:34 chregu Exp $ /** * This class takes a PEAR::DB-Result Object, a sql-query-string or an array @@ -43,10 +43,10 @@ * $xmlstring = $sql2xml->getXML(); * * More documentation and a tutorial/how-to can be found at -* http://www.nomad.ch/php/sql2xml +* http://php.chregu.tv/sql2xml * * @author Christian Stocker <chregu@nomad.ch> -* @version $Id: sql2xml.php,v 1.1 2001/08/03 07:22:44 chregu Exp $ +* @version $Id: sql2xml.php,v 1.2 2001/08/16 08:14:34 chregu Exp $ * @package XML */ class XML_sql2xml { @@ -113,6 +113,7 @@ /** * The Root of the domxml object * I'm not sure, if we need this as a class variable.... + * could be replaced by domxml_root($this->xmldoc); * * @var object DomNode * @acces private @@ -176,6 +177,7 @@ function XML_sql2xml ($dsn=Null,$root = "root") { // if it's a string, then it must be a dsn-identifier; + if (is_string($dsn)) { include_once ("DB.php"); @@ -188,7 +190,7 @@ } - elseif (DB::isError($dsn)) + elseif (is_object($dsn) && DB::isError($dsn)) { print "The given param for XML_sql2xml was not valid in file ".__FILE__." at line ".__LINE__."<br>\n"; return new DB_Error($dsn->code,PEAR_ERROR_DIE); @@ -200,7 +202,6 @@ $this->db = $dsn; } - $this->xmldoc = domxml_new_xmldoc('1.0'); if ($root) { $this->xmlroot = $this->xmldoc->add_root($root); @@ -220,9 +221,18 @@ */ function add ($resultset) { - // if string, then it's a query... + // if string, then it's a query, a xml-file or a xml-string... if (is_string($resultset)) { - $this->AddSql($resultset); + if (preg_match("/\.xml$/",$resultset)) { + $this->AddXmlFile($resultset); + } + elseif (preg_match("/.*select.*from.*/" , $resultset)) { + $this->AddSql($resultset); + } + else { + $this->AddXmlString($resultset); + } + } // if array, then it's an array... elseif (is_array($resultset)) { @@ -235,6 +245,36 @@ } /** + * Adds the content of a xml-file to $this->xmldoc, on the same level + * as a normal resultset (mostly just below <root>) + * + * @param string filename + * @access public + * @see doXmlString2Xml() + */ + + function addXmlFile($file) + { + $fd = fopen( $file, "r" ); + $content = fread( $fd, filesize( $file ) ); + fclose( $fd ); + $this->doXmlString2Xml($content); + } + + /** + * Adds the content of a xml-string to $this->xmldoc, on the same level + * as a normal resultset (mostly just below <root>) + * + * @param string xml + * @access public + * @see doXmlString2Xml() + */ + function addXmlString($string) + { + $this->doXmlString2Xml($string); + } + + /** * Adds an additional pear::db_result resultset to $this->xmldoc * * @param Object db_result result from a DB-query @@ -256,7 +296,16 @@ */ function addSql($sql) { + $result = $this->db->query($sql); + + //very strange + if (PEAR::isError($result->result)) { + print "You have an SQL-Error:<br>".$result->result->userinfo; + print "<br>"; + new DB_Error($result->result->code,PEAR_ERROR_DIE); + } + $this->doSql2Xml($result); } @@ -288,7 +337,8 @@ */ function getXML($result = Null) { - return domxml_dumpmem($this->getXMLObject($result)); + $xmldoc = $this->getXMLObject($result); + return $xmldoc->dumpmem(); } /** @@ -321,6 +371,7 @@ if (DB::IsError($result)) { print "Error in file ".__FILE__." at line ".__LINE__."<br>\n"; + print $result->userinfo."<br>\n"; new DB_Error($result->code,PEAR_ERROR_DIE); } @@ -328,6 +379,7 @@ // (should be in 4.0.6) // BE CAREFUL: if you have fields with the same name in different tables, you will get errors // later, since DB_FETCHMODE_ASSOC doesn't differentiate that stuff. + $this->LastResult = &$result; if (!method_exists($result,"tableInfo") || ! ($tableInfo = $result->tableInfo(False))) { @@ -356,21 +408,30 @@ // initialize db hierarchy... $parenttable = "root"; $tableInfo["parent_key"]["root"] = 0; + foreach ($tableInfo as $key => $value) { if (is_int($key)) { + // if the sql-query had a function the table starts with a # (only in mysql i think....), then give the field the name of the table before... + if (preg_match ("/^#/",$value["table"]) || strlen($value["table"]) == 0) { + $value["table"] = $tableInfo[($key - 1)]["table"] ; + $tableInfo[$key]["table"] = $value["table"]; + } + + if (is_null($tableInfo["parent_table"][$value["table"]])) { $tableInfo["parent_key"][$value["table"]] = $key; $tableInfo["parent_table"][$value["table"]] = $parenttable; $parenttable = $value["table"] ; } + } //if you need more tableInfo for later use you can write a function addTableInfo.. $this->addTableInfo($key, $value, &$tableInfo); } - + // end initialize // if user made some own tableInfo data, merge them here. @@ -379,7 +440,7 @@ $tableInfo = $this->array_merge_clobber($tableInfo,$this->user_tableInfo); } $parent[root] = $this->insertNewResult(&$tableInfo); - + while ($FirstFetchDone || $res = $result->FetchRow($fetchmode)) { //FirstFetchDone is only for emulating tableInfo, as long as not all dbs support tableInfo. can go away later @@ -410,9 +471,10 @@ } } - - $this->insertNewElement($parent[$tableInfo[$key]["table"]], $res, $key, &$tableInfo, &$subrow); - + if ( $parent[$tableInfo[$key]["table"]] != Null) + { + $this->insertNewElement($parent[$tableInfo[$key]["table"]], $res, $key, &$tableInfo, &$subrow); + } } } @@ -423,6 +485,8 @@ return $this->xmldoc; } + + /** * For adding whole arrays to $this->xmldoc * @@ -433,16 +497,17 @@ */ function DoArray2Xml ($array, $parent) { + while (list($key, $val) = each($array)) { $tableInfo[$key]["table"]= $this->tagNameResult; $tableInfo[$key]["name"] = $key; } + if ($this->user_tableInfo) { $tableInfo = $this->array_merge_clobber($tableInfo,$this->user_tableInfo); } - foreach ($array as $key=>$value) { if (is_array($value) ) { @@ -454,9 +519,11 @@ } else { + $valuenew = $value; $keynew = $key; } + $rec2 = $this->insertNewRow($parent, $valuenew, $keynew, &$tableInfo); $this->DoArray2xml($value,$rec2); } @@ -475,20 +542,31 @@ * of this class. * * @param array options to be passed to the class + * @param bool if the old suboptions should be deleted * @access public * @see $nested,$user_options,$user_tableInfo */ - function setOptions($options) { + function setOptions($options,$delete = False) { //set options if (is_array($options)) { foreach ($options as $option => $value) { - if (isset($this->$option)) { - $this->$option = $value; - } - + if (isset($this->{$option})) + { + if (is_array($value) && ! $delete) + { + foreach ($value as $suboption => $subvalue) + { + $this->{$option}["$suboption"] = $subvalue; + } + } + else + { + $this->$option = $value; + } + } } } } @@ -523,7 +601,7 @@ */ function insertNewRow($parent_row, $res, $key, &$metadata) { - return $parent_row->new_child($this->tagNameRow, NULL); + return $parent_row->new_child($this->tagNameRow, Null); } @@ -605,5 +683,28 @@ } return $newarray; } + + /** + * Adds a xml string to $this->xmldoc. + * It's inserted on the same level as a "normal" resultset, means just as a children of <root> + * + * I found no cleaner method than the below one. it's maybe nasty (xmlObject->string->xmlObject), + * but it works. If someone knows how to add whole DomNodes to another one, let me know... + * + * @param string xml string + * @acces private + */ + + function doXmlString2Xml ($string) + { + $MainXmlString = $this->xmldoc->dumpmem(); + $string = preg_replace("/<\?xml.*\?>/","",$string); + $MainXmlString = preg_replace("/<".$this->xmlroot->name."\/>/","<".$this->xmlroot->name."></".$this->xmlroot->name.">",$MainXmlString); + $MainXmlString = preg_replace("/<\/".$this->xmlroot->name.">/",$string."</".$this->xmlroot->name.">",$MainXmlString); + $this->xmldoc = xmldoc($MainXmlString); + $this->xmlroot = $this->xmldoc->root(); + } + + } ?> Index: pear/XML_sql2xml/sql2xml_ext.php diff -u pear/XML_sql2xml/sql2xml_ext.php:1.1 pear/XML_sql2xml/sql2xml_ext.php:1.2 --- pear/XML_sql2xml/sql2xml_ext.php:1.1 Fri Aug 3 03:22:44 2001 +++ pear/XML_sql2xml/sql2xml_ext.php Thu Aug 16 04:14:34 2001 @@ -12,61 +12,87 @@ // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ -// | Authors: Christian Stocker <chregu@nomad.ch> | +// | Authors: Christian Stocker <chregu@phant.ch> | // +----------------------------------------------------------------------+ // -// $Id: sql2xml_ext.php,v 1.1 2001/08/03 07:22:44 chregu Exp $ +// $Id: sql2xml_ext.php,v 1.2 2001/08/16 08:14:34 chregu Exp $ require_once ("XML/sql2xml.php"); /** - * This class shows with a example, how the base sql2xml-class + * This class shows with an example, how the base sql2xml-class * could be extended. * * Usage example * - * include_once ("DB.php"); * include_once("XML/sql2xml_ext.php"); - * $xml = new xml_sql2xml_ext; * $options= array( user_options => array (xml_seperator =>"_", * element_id => "id"), * ); - * $db = DB::connect("mysql://root@localhost/xmltest"); - * $xml = new xml_sql2xml; - * $result = $db->query("select * from bands"); - * $xmlstring = $xml->getxml($result,$options)); + * $sql2xml = new xml_sql2xml_ext("mysql://root@localhost/xmltest"); + * $sql2xml->SetOptions($options); + * $xmlstring = $sql2xml->getxml("select * from bands"); * more examples and outputs on - * http://www.nomad.ch/php/sql2xml/ + * http://php.chregu.tv/sql2xml/ * for the time being * * @author Christian Stocker <chregu@nomad.ch> - * @version $Id: sql2xml_ext.php,v 1.1 2001/08/03 07:22:44 chregu Exp $ + * @version $Id: sql2xml_ext.php,v 1.2 2001/08/16 08:14:34 chregu Exp $ */ class XML_sql2xml_ext extends XML_sql2xml { - function insertNewRow($parent_row, $res, $key, &$tableInfo) + function XML_sql2xml_ext ($dsn=Null,$root = "root") { + $this->XML_sql2xml($dsn,$root); + // DefaultValues for user_options + + $user_options = array ( + xml_seperator =>"_", + element_id => "ID", + print_empty_ids => False, + ); + + $this->setOptions(array("user_options"=>$user_options)); + + } + + function insertNewRow ($parent_row, $res, $key, &$tableInfo) + { + if (!$tableInfo[$key]["table"]) { + $tableInfo[$key]["table"] = $this->tagNameResult; + } + if ($this->user_options[element_id] && !$res[$tableInfo["id"][$tableInfo[$key]["table"]]] && !$this->user_options[print_empty_ids]) + { + return Null; + } $new_row= $parent_row->new_child($tableInfo[$key]["table"],Null); /* make an unique ID attribute in the row element with tablename.id if there's an id otherwise just make an unique id with the php-function, just that there's a unique id for this row. CAUTION: This ID changes every time ;) (if no id from db-table) */ - $new_row->set_attribute("type","row"); + $this->SetAttribute($new_row,"type","row"); + if ($res[$tableInfo["id"][$tableInfo[$key]["table"]]]) { - if ($res[$tableInfo["id"][$tableInfo[$key]["table"]]] == $this->user_options[id]) + /* make attribute selected if ID = selected_id OR tableName.ID = selected_id. for the second case + you can give an array for multiple selected entries */ + + if ($res[$tableInfo["id"][$tableInfo[$key]["table"]]] == $this->user_options[selected_id] + || $tableInfo[$key]["table"].$res[$tableInfo["id"][$tableInfo[$key]["table"]]] == $this->user_options[selected_id] + || (is_array($this->user_options[selected_id]) && in_array($tableInfo[$key]["table"].$res[$tableInfo["id"][$tableInfo[$key]["table"]]],$this->user_options[selected_id]))) + { - $new_row->set_attribute("selected", "selected"); + $this->SetAttribute($new_row,"selected", "selected"); } - $new_row->set_attribute("ID", utf8_encode($tableInfo[$key]["table"] . $res[$tableInfo["id"][$tableInfo[$key]["table"]]])); + $this->SetAttribute($new_row,"ID", utf8_encode($tableInfo[$key]["table"] . $res[$tableInfo["id"][$tableInfo[$key]["table"]]])); } else { $this->IDcounter[$tableInfo[$key]["table"]]++; - $new_row->set_attribute("ID", $tableInfo[$key]["table"].$this->IDcounter[$tableInfo[$key]["table"]]); + $this->SetAttribute($new_row,"ID", $tableInfo[$key]["table"].$this->IDcounter[$tableInfo[$key]["table"]]); } @@ -74,42 +100,49 @@ } - function insertNewResult(&$tableInfo) { - - if ($this->user_options["result_root"]) + function insertNewResult (&$tableInfo) { + + if ($this->user_options["result_root"]) $result_root = $this->user_options["result_root"]; - else + elseif ($tableInfo[0]["table"]) $result_root = $tableInfo[0]["table"]; - + else + $result_root = "resultset"; + if ($this->xmlroot) $xmlroot=$this->xmlroot->new_child($result_root,Null); else $xmlroot= $this->xmldoc->add_root($result_root); - $xmlroot->set_attribute("type","resultset"); + $this->SetAttribute($xmlroot,"type","resultset"); return $xmlroot; } - - function insertNewElement($parent, $res, $key, &$tableInfo, &$subrow) { + + function insertNewElement ($parent, $res, $key, &$tableInfo, &$subrow) { if (is_array($this->user_options["attributes"]) && in_array($tableInfo[$key]["name"],$this->user_options["attributes"])) { - $subrow=$parent->set_attribute($tableInfo[$key]["name"],$this->xml_encode($res[$key])); + $subrow=$this->SetAttribute($parent,$tableInfo[$key]["name"],$this->xml_encode($res[$key])); } elseif ($this->user_options["xml_seperator"]) { //the preg should be only done once.... $i = 0; preg_match_all("/([^" . $this->user_options["xml_seperator"] . "]+)" . $this->user_options[xml_seperator] . "*/", $tableInfo[$key]["name"], $regs); - $subrow[$regs[1][-1]] = $parent; + + + $subrow[$regs[1][-1]] = $parent; // here we separate db fields to subtags. for ($i = 0; $i < (count($regs[1]) - 1); $i++) { - if ( ! $subrow[$regs[1][$i]]) { - $subrow[$regs[1][$i]] = $subrow[$regs[1][$i - 1]]->new_child($regs[1][$i], NULL); + $beforetags .=$regs[1][$i]."_"; + $before[$i] = $beforetags; + if ( ! $subrow[$before[$i]] ) { + $subrow[$before[$i]] = $subrow[$before[$i - 1]]->new_child($regs[1][$i], NULL); } } - $subrows = $subrow[$regs[1][$i - 1]]->new_child($regs[1][$i], $this->xml_encode($res[$key])); + $subrows = $subrow[$before[$i - 1]]->new_child($regs[1][$i], $this->xml_encode($res[$key])); + } else { @@ -127,5 +160,17 @@ $tableInfo[$key]["name"] = $this->user_options["field_translate"][$value["name"]]; } } + + // A wrapper for set setattr/set_attribute, since the function changed in php 4.0.6... + function SetAttribute ($node,$name,$value) { + if (method_exists($node,"Set_attribute")) + { + return $node->Set_Attribute($name,$value); + } + else { + return $node->setattr($name,$value); + } + } + } ?>
« previous php.pear.cvs (#549) next »