Name('Rob')
* ->Age('34')
* ->Weight('185')
*
* to produce:
* Rob
* 34
* 185
*
* - Add attributes to previous node using ->attribs :
* $b->Person
* ->attribs( array(
* 'age' => 34,
* 'weight' => 185,
* ))
*
* to produce:
*
*
* - Build out an independent or nested set of nodes using ->child()
* and add them as children of a node :
* $people = $b->child();
* foreach (array('Rob','Casey','Brennen','Dave') as $name)
* $people->$name;
* $b->People($people);
*
* to produce[1]:
*
*
*
*
*
*
*
* - Add children to previous node using ->nest :
* $b->People;
* foreach (array('Rob','Casey','Brennen','Dave') as $name)
* $b->nest( $b->child()->$name );
*
* to produce:
*
*
*
*
*
*
*
* - Fetch a string representation of the document :
* print $b->People->Places->Things->string( $want_html );
*
* - Fetch the DOMDocument object for beating with hammers :
* $b->Youll->Hate->Yourself->domodc();
*
*
* Notes:
* 1: Thankfully, DOMDocument doesn't know how to create singleton tags,
* so it just creates empty tag pairs:
. D:
*/
class Builder {
private $domdoc;
private $namespace = '';
private $namespace_url = '';
private $last_node = false;
public function __construct(){
$this->domdoc = new DOMDocument('1.0');
}
public function attribs( $attributes ){
foreach ($attributes as $name => $value)
$this->last_node()->setAttribute($name, $value);
return $this;
}
public function child(){
$x = new static;
$x->xmlns($this->namespace, $this->namespace_url);
return $x;
}
public function nest($document){
if ($document == null)
return $this;
$node = $this->last_node();
if ($document instanceof DOMDocument)
$kids = $document;
elseif ($document instanceof static)
$kids = $document->domdoc;
else
throw new InvalidArgumentException(' nest only knows how to import children from a DOMDocument or a SparkLib\Xml\Builder.');
if (count($kids) == 0)
return $this;
foreach ($kids->childNodes as $kid) {
$node->appendChild(
$this->domdoc->importNode($kid, true)
);
}
return $this;
}
public function last_node(){
$node = $this->last_node;
if ($node === false)
throw new \LogicException('Unable to set attributes for nonexistant previous node');
return $node;
}
public function xmlns($namespace, $url){
$this->namespace = $namespace;
$this->namespace_url = $url;
return $this;
}
public function node($name, $value = '', $attributes = array(), $children = null){
if (strlen($this->namespace) > 0)
$node = new DOMElement("{$this->namespace}:{$name}", '', $this->namespace_url);
else
$node = new DOMElement($name);
$node->nodeValue = $value;
$this->last_node = $node;
$this->domdoc->appendChild($node);
$this->attribs($attributes);
$this->nest($children);
return $this;
}
public function __get($name){
$this->node($name);
return $this;
}
public function __call($name, $arguments){
if (count($arguments) <= 0) {
$this->node($name);
return $this;
}
$first = $arguments[0];
if ($first instanceof static)
$this->node($name, '', array(), $first->domdoc);
elseif ($first instanceof DOMDocument)
$this->node($name, '', array(), $first);
else
$this->node($name, $first);
return $this;
}
public function domdoc(){
return $this->domdoc;
}
public function string($html = false){
if ($html)
return $this->domdoc->saveHTML();
else
return $this->domdoc->saveXML();
}
}