<?php
if(!defined("METAL_LIBRARY_XML_XML_WRITER_CLASS"))
{
define("METAL_LIBRARY_XML_XML_WRITER_CLASS",1);
/*
*
* Copyright © (C) Manuel Lemos 2001-2002
*
* @(#) $Id: xmlwriterclass.class,v 1.32 2002/10/17 05:38:11 mlemos Exp $
*
*/
class xml_writer_class
{
/*
* Protected variables
*
*/
var $structure=array();
var $nodes=array();
/*
* Public variables
*
*/
var $stylesheet="";
var $stylesheettype="text/xsl";
var $dtdtype="";
var $dtddefinition="";
var $dtdurl="";
var $outputencoding="utf-8";
var $inputencoding="iso-8859-1";
var $linebreak="\n";
var $indenttext=" ";
var $generatedcomment="Generated by: http://www.phpclasses.org/xmlwriter \$Revision: 1.32 \$";
var $error="";
/*
* Protected functions
*
*/
Function escapedata($data)
{
$position=0;
$length=strlen($data);
$escapeddata="";
for(;$position<$length;)
{
$character=substr($data,$position,1);
$code=Ord($character);
switch($code)
{
case 34:
$character=""";
break;
case 38:
$character="&";
break;
case 39:
$character="'";
break;
case 60:
$character="<";
break;
case 62:
$character=">";
break;
default:
if($code<32)
$character=("&#".strval($code).";");
break;
}
$escapeddata.=$character;
$position++;
}
return $escapeddata;
}
Function encodedata($data,&$encodeddata)
{
if(!strcmp($this->inputencoding,$this->outputencoding))
$encodeddata=$this->escapedata($data);
else
{
switch(strtolower($this->outputencoding))
{
case "utf-8":
if(!strcmp(strtolower($this->inputencoding),"iso-8859-1"))
{
$encoded_data=utf8_encode($this->escapedata($data));
$encodeddata=$encoded_data;
}
else
{
$this->error=("can not encode iso-8859-1 data in ".$this->outputencoding);
return 0;
}
break;
case "iso-8859-1":
if(!strcmp(strtolower($this->inputencoding),"utf-8"))
{
$decoded=utf8_decode($data);
$encodeddata=$this->escapedata($decoded);
}
else
{
$this->error=("can not encode utf-8 data in ".$this->outputencoding);
return 0;
}
break;
default:
$this->error=("can not encode data in ".$this->inputencoding);
return 0;
}
}
return 1;
}
Function writetag(&$output,$path,$indent)
{
$tag=$this->structure[$path]["Tag"];
$output.=("<".$tag);
$attributecount=count($this->structure[$path]["Attributes"]);
if($attributecount>0)
{
$attributes=$this->structure[$path]["Attributes"];
Reset($attributes);
$end=(GetType($key=Key($attributes))!="string");
for(;!$end;)
{
$output.=(" ".$key."=\"".$attributes[$key]."\"");
Next($attributes);
$end=(GetType($key=Key($attributes))!="string");
}
}
$elements=$this->structure[$path]["Elements"];
if($elements>0)
{
$output.=">";
$doindent=$this->structure[$path]["Indent"];
$elementindent=(($doindent) ? $this->linebreak.$indent.$this->indenttext : "");
$element=0;
for(;$element<$elements;)
{
$elementpath=($path.",".strval($element));
$output.=$elementindent;
if(IsSet($this->nodes[$elementpath]))
{
if(!($this->writetag($output,$elementpath,$indent.$this->indenttext)))
return 0;
}
else
$output.=$this->structure[$elementpath];
$element++;
}
$output.=((($doindent) ? $this->linebreak.$indent : "")."</".$tag.">");
}
else
$output.="/>";
return 1;
}
/*
* Public functions
*
*/
Function write(&$output)
{
if(strcmp($this->error,""))
return 0;
if(!(IsSet($this->structure["0"])))
{
$this->error="XML document structure is empty";
return 0;
}
$output=("<?xml version=\"1.0\" encoding=\"".$this->outputencoding."\"?>".$this->linebreak);
if(strcmp($this->dtdtype,""))
{
$output.=("<!DOCTYPE ".$this->structure["0"]["Tag"]." ");
switch($this->dtdtype)
{
case "INTERNAL":
if(!strcmp($this->dtddefinition,""))
{
$this->error="it was not specified a valid internal DTD definition";
return 0;
}
$output.=("[".$this->linebreak.$this->dtddefinition.$this->linebreak."]");
break;
case "SYSTEM":
if(!strcmp($this->dtdurl,""))
{
$this->error="it was not specified a valid system DTD url";
return 0;
}
$output.="SYSTEM";
if(strcmp($this->dtddefinition,""))
$output.=(" \"".$this->dtddefinition."\"");
$output.=(" \"".$this->dtdurl."\"");
break;
case "PUBLIC":
if(!strcmp($this->dtddefinition,""))
{
$this->error="it was not specified a valid public DTD definition";
return 0;
}
$output.=("PUBLIC \"".$this->dtddefinition."\"");
if(strcmp($this->dtdurl,""))
$output.=(" \"".$this->dtdurl."\"");
break;
default:
$this->error="it was not specified a valid DTD type";
return 0;
}
$output.=(">".$this->linebreak);
}
if(strcmp($this->stylesheet,""))
{
if(!strcmp($this->stylesheettype,""))
{
$this->error="it was not specified a valid stylesheet type";
return 0;
}
$output.=("<?xml-stylesheet type=\"".$this->stylesheettype."\" href=\"".$this->stylesheet."\"?>".$this->linebreak);
}
if(strcmp($this->generatedcomment,""))
$output.=("<!-- ".$this->generatedcomment." -->".$this->linebreak);
return $this->writetag($output,"0","");
}
Function addtag($tag,&$attributes,$parent,&$path,$indent)
{
if(strcmp($this->error,""))
return 0;
$path=((!strcmp($parent,"")) ? "0" : ($parent.",".strval($this->structure[$parent]["Elements"])));
if(IsSet($this->structure[$path]))
{
$this->error=("tag with path ".$path." is already defined");
return 0;
}
$encodedattributes=array();
Reset($attributes);
$end=(GetType($attribute_name=Key($attributes))!="string");
for(;!$end;)
{
$encodedattributes[$attribute_name]="";
if(!($this->encodedata($attributes[$attribute_name],$encoded_data)))
return 0;
$encodedattributes[$attribute_name]=$encoded_data;
Next($attributes);
$end=(GetType($attribute_name=Key($attributes))!="string");
}
$this->structure[$path]=array(
"Tag"=>$tag,
"Attributes"=>$encodedattributes,
"Elements"=>0,
"Indent"=>$indent
);
$this->nodes[$path]=1;
if(strcmp($parent,""))
$this->structure[$parent]["Elements"]=($this->structure[$parent]["Elements"]+1);
return 1;
}
Function adddata($data,$parent,&$path)
{
if(strcmp($this->error,""))
return 0;
if(!(IsSet($this->structure[$parent])))
{
$this->error=("the parent tag path".$path."is not defined");
return 0;
}
if(!strcmp($data,""))
return 1;
$path=($parent.",".strval($this->structure[$parent]["Elements"]));
if(!($this->encodedata($data,$encoded_data)))
return 0;
$this->structure[$path]=$encoded_data;
$this->structure[$parent]["Elements"]=($this->structure[$parent]["Elements"]+1);
return 1;
}
Function adddatatag($tag,&$attributes,$data,$parent,&$path)
{
return $this->addtag($tag,$attributes,$parent,$path,0) && $this->adddata($data,$path,$datapath);
}
};
}
?>