Pristup koji sam u svojio prilikom izrade web sajta je u sustini izgradnja web servisa, razvoj svojih xml dokumenata (shema), kao i što transparentiji povezivanje shema i relacione baze. Kako za MySQL ne postoji jednostavan način transformacije relacione tabele u XML dokument (zbog razlika je u strukturi drveta i table) počeo sam da izgradjujem svoje klase koje bi se orađivale tu transofrmaciju.
Ne mogu se pohvaliti da sam napravio bas najsretniji način strukturiranja tabele u stablo. Koristim array za opis transformacije (grupisanje podčvorova). Prirodniji pristup bi verovatno bio da za opis te strukture koristim objekte, ali jednostavno nisam nasao vremena da razvijem klase za opis te transformacije.
Code:
class SQL_get extends SQL_connection{
var $data; // SQL result data holder
// izvrsava sql komandu i rezultat smesta u $this->data array, rezultati se smestaju kao
// data[0][ime],data[0][id],data[1][name]....
function sql_query($sql){
if ($result = mysql_query($sql)){
return true;
}else{
return false;
}
}
function sql_get_data($sql){
if ($result = mysql_query($sql)){
$i = 0;
while ($i < mysql_num_fields($result)) {
$meta[$i] = mysql_field_flags($result,$i);
$i++;
}
$i=0;
while ($row = @mysql_fetch_array($result, MYSQL_ASSOC)) {
$j=0;
foreach ($row as $k => $v) {
if (strpos($meta[$j],'set')=== false) {
$this->data[$i][$k]=$v;
}else{
$this->data[$i][$k] = explode(",",$v);
}
$j++;
}
$i++;
}
return true;
}else{
$this->error_loging("Invalid query: " . mysql_error(), $sql);
return false;
}
}
function xml_set_walk(&$dom,$tag_name='',&$node,$key,$depth='',$loop_key=''){
do {
$new_node = $node->append_child($dom->create_element($tag_name));
foreach ($depth as $field_name => $v){
$v1 = $this->data[$key][$field_name];
if (is_array($v1)){
foreach ($v1 as $v2) {
$temp = $new_node->append_child($dom->create_element($v['tag_name']));
$temp->append_child($dom->create_text_node($v2));
}
}else{
$temp = $new_node->append_child($dom->create_element($v['tag_name']));
$temp->append_child($dom->create_text_node($v1));
}
if (isset($v['__depth']) && is_array($v['__depth'])){
$key = $this->xml_set_walk($dom,$v['__depth_tag'],$new_node,$key,$v['__depth'],$field_name) -1;
}
}
$key ++;
}while ($loop_key!='' && ($this->data[$key][$loop_key]===$this->data[$key-1][$loop_key]));
return $key;
}
function xml_set($main_tag='', $depth = null){
if ($main_tag=='') $main_tag = get_class($this);
$main_node = $this->xml;
if ($this->data) {
if (!is_array($depth)){
foreach ($this->data as $k => $v) {
$fc = $main_node->append_child($this->dom_doc->create_element($main_tag));
foreach ($v as $k1 => $v1) {
if (is_array($v1)){
foreach ($v1 as $v2){
if (is_a($v2,"DOMNode")){
$temp_child = $v2->clone_node(true);
$fc->append_child($temp_child);
}else{
$temp = $fc->append_child($this->dom_doc->create_element($k1));
$temp->append_child($this->dom_doc->create_text_node($v2));
}
}
}else if (is_a($v1,"DOMNode")){
$temp_child = $v1->clone_node(true);
$tmp = $fc->append_child($temp_child);
}else{
$temp = $fc->append_child($this->dom_doc->create_element($k1));
$temp->append_child($this->dom_doc->create_text_node($v1));
}
}
}
}else{
$key = 0;
while ($key < count($this->data)){
$key = $this->xml_set_walk($this->dom_doc,$main_tag,$main_node,$key,$depth);
}
}
}
}
// konstruktor
function SQL_get( &$dom_doc, &$doc_element, $sql=NULL,$main_tag=''){
$this->set_dom_doc($dom_doc);
$this->set_dom_element($doc_element);
$this->SQL_connection();
if ($sql && $this->sql_connected) {
$this->sql_get_data($sql);
}
}
}
Kao što možete primetiti u gornjem kodu nije korišćen PEAR:MDB2 trenutno se upoznajem sa njim i verovatno ću ga nadalje koristiti.
Samo mapiranje izgleda odprilike ovako:
Code:
$arr = array ('id' => array ('tag_name' => 'id' , '__depth_tag' => 'proizvodi', '__depth' =>
array ( 'naziv' => array ('tag_name' => 'naziv'),
'pid' => array ('tag_name' => 'id'),
)
),
'edition_id' => array ('tag_name' => 'edition_id'),
'visible' => array ('tag_name' => 'visible'),
'name' => array ('tag_name' => 'name'),
);
Pristup koji mi se jako svideo nažalost potice od mrskog nam M$ je vezan za SQLXML, elem oni koriste prošireni XSD da dokumentuju u okviru sheme koji nod se za koje SQL polje vezuje.
http://msdn2.microsoft.com/en-us/library/ms171779.aspx
Code:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:element name="Contact" sql:relation="Person.Contact" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FName"
sql:field="FirstName"
type="xsd:string" />
<xsd:element name="LName"
sql:field="LastName"
type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="ConID"
sql:field="ContactID"
type="xsd:integer" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
Nešto na tragu onoga što sam radio:
http://pear.php.net/package/XML_sql2xml
Ovo je na brzinu kako generišem XML dokumente iz baze podataka, pored toga razvio sam par klasa za generisanje XML podataka iz fajl sistema (ID3 tagovi iz MP3 fajlova, naslovi, autor, datumi iz PDFova, EXIF iz slika...) i direktno korišćenje xml fajlova kao izvora podataka.
Uskoro o XSL transformacijama (tj. zanimljivi deo priče)
poz, utvara