<?php
$xpath = "/bids_offers/market_submit/sem_gen_technical_offer/block_deloading/point[2]";
$xml = new EformDOMDocument();
$root = $xml->createElement("bids_offers");
$xml->appendChild($root);
$xml->buildMissingTree($xpath);
$xml->formatOutput = true;
echo $xml->saveXML();
class EformDOMDocument extends DOMDocument {
public $xpath;
public function __construct($version = null, $encoding = null) {
parent::__construct($version, $encoding);
$this->xpath = new DOMXPath($this);
}
public function setAttributeX($path, $attributeName, $attributeValue) {
// check if path returns anything valid
if ($this->xpath->query($path)->length == 0) {
$this->buildMissingTree($path);
}
$this->xpath->query($path)->item(0)->setAttribute($attributeName, $attributeValue);
}
public function buildMissingTree($path) {
$missingNodes = array();
$tempPath = $path;
// build an array of missing elements in the path
while ($this->xpath->query($tempPath)->length == 0) {
$tempName = basename($tempPath);
$tempPath = dirname($tempPath);
// deal with such: testnode[@type='HOT'] or [#]
if (strpos($tempName, '[') === FALSE) {
// no attributes use $tempName
$missingNodes[] = $this->createElement($tempName);
} else {
// split element name and attribute, create both separate, append attribute to element, push into the aray
$tempHolder = explode('[', $tempName);
$tempElement = $this->createElement($tempHolder[0]);
// [1] is attribute, clean it up, split name and value
if (strpos($tempHolder[1], '@') !== FALSE) {
// element has attiribute if it has @ in the path piece
$attParam = str_replace(array('@', '\'', ']'), '', $tempHolder[1]);
$attribute = explode('=', $attParam);
$tempElement->setAttribute($attribute[0], $attribute[1]);
} // otherwise its a number of the node in the sequence, skip it, as if xml is generated is in order,
//previous nodes should exist already
$missingNodes[] = $tempElement;
$tempElement = null;
}
}
// build the structure with missing elements (use $missingNodes array)
// get existing end
echo $tempPath;
var_dump($missingNodes);
$currentElement = $this->xpath->query($tempPath)->item(0);
while (($newElement = array_pop($missingNodes) !== NULL)) {
$currentElement->appendChild($newElement);
$currentElement = $newElement;
}
}
/**
* Checks if document has at least one element with a name (and optional attribute) provided
*
* @param string $name
* @return mixed
*/
public function hasElement($name, $attribute = '') {
$elements = $this->getElementsByTagName($name);
if ($elements->length > 0) {
if ($attribute == '') {
return true;
}
// if attribute provided, check through the list for the element with provided attribute
for ($i = 0; $i < $elements->length; $i++) {
// TODO fix that checks on attibute value too, not just name
if ($elements->item($i)->hasAttribute($attribute)) {
return $elements->item($i);
//return true;
}
}
}
return false;
}
/**
*
* @param string $name
* @param string $attributeParameters provided as "attr1name=value1;attr2name=value2...etc."
* @return DOMElement
*/
public function createElementWithAttributes($name, $attributeParameters = '') {
$element = $this->createElement($name);
// atributes provided as "attr1name=value1;attr2name=value2...etc."
if ($attributeParameters != '') {
// separate multiple parameters
$attributes = explode(';', $attributeParameters);
// add parameters to the element
foreach ($attributes as $attribute) {
$keyvalue = explode('=', $attribute);
$element->setAttribute($keyvalue[0], $keyvalue[1]);
}
}
return $element;
}
}
/bids_offersarray(4) {
[0]=>
object(DOMElement)#4 (17) {
["tagName"]=>
string(5) "point"
["schemaTypeInfo"]=>
NULL
["nodeName"]=>
string(5) "point"
["nodeValue"]=>
string(0) ""
["nodeType"]=>
int(1)
["parentNode"]=>
NULL
["childNodes"]=>
string(22) "(object value omitted)"
["firstChild"]=>
NULL
["lastChild"]=>
NULL
["previousSibling"]=>
NULL
["attributes"]=>
string(22) "(object value omitted)"
["ownerDocument"]=>
string(22) "(object value omitted)"
["namespaceURI"]=>
NULL
["prefix"]=>
string(0) ""
["localName"]=>
string(5) "point"
["baseURI"]=>
NULL
["textContent"]=>
string(0) ""
}
[1]=>
object(DOMElement)#5 (17) {
["tagName"]=>
string(15) "block_deloading"
["schemaTypeInfo"]=>
NULL
["nodeName"]=>
string(15) "block_deloading"
["nodeValue"]=>
string(0) ""
["nodeType"]=>
int(1)
["parentNode"]=>
NULL
["childNodes"]=>
string(22) "(object value omitted)"
["firstChild"]=>
NULL
["lastChild"]=>
NULL
["previousSibling"]=>
NULL
["attributes"]=>
string(22) "(object value omitted)"
["ownerDocument"]=>
string(22) "(object value omitted)"
["namespaceURI"]=>
NULL
["prefix"]=>
string(0) ""
["localName"]=>
string(15) "block_deloading"
["baseURI"]=>
NULL
["textContent"]=>
string(0) ""
}
[2]=>
object(DOMElement)#6 (17) {
["tagName"]=>
string(23) "sem_gen_technical_offer"
["schemaTypeInfo"]=>
NULL
["nodeName"]=>
string(23) "sem_gen_technical_offer"
["nodeValue"]=>
string(0) ""
["nodeType"]=>
int(1)
["parentNode"]=>
NULL
["childNodes"]=>
string(22) "(object value omitted)"
["firstChild"]=>
NULL
["lastChild"]=>
NULL
["previousSibling"]=>
NULL
["attributes"]=>
string(22) "(object value omitted)"
["ownerDocument"]=>
string(22) "(object value omitted)"
["namespaceURI"]=>
NULL
["prefix"]=>
string(0) ""
["localName"]=>
string(23) "sem_gen_technical_offer"
["baseURI"]=>
NULL
["textContent"]=>
string(0) ""
}
[3]=>
object(DOMElement)#7 (17) {
["tagName"]=>
string(13) "market_submit"
["schemaTypeInfo"]=>
NULL
["nodeName"]=>
string(13) "market_submit"
["nodeValue"]=>
string(0) ""
["nodeType"]=>
int(1)
["parentNode"]=>
NULL
["childNodes"]=>
string(22) "(object value omitted)"
["firstChild"]=>
NULL
["lastChild"]=>
NULL
["previousSibling"]=>
NULL
["attributes"]=>
string(22) "(object value omitted)"
["ownerDocument"]=>
string(22) "(object value omitted)"
["namespaceURI"]=>
NULL
["prefix"]=>
string(0) ""
["localName"]=>
string(13) "market_submit"
["baseURI"]=>
NULL
["textContent"]=>
string(0) ""
}
}
Catchable fatal error: Argument 1 passed to DOMNode::appendChild() must be an instance of DOMNode, boolean given, called in /in/ebVBR on line 6 and defined in /in/ebVBR on line 63
Process exited with code 255.
Output for 5.2.6 - 5.2.17, 5.3.0 - 5.3.10, 5.4.0
/bids_offersarray(4) {
[0]=>
object(DOMElement)#4 (0) {
}
[1]=>
object(DOMElement)#5 (0) {
}
[2]=>
object(DOMElement)#6 (0) {
}
[3]=>
object(DOMElement)#7 (0) {
}
}
Catchable fatal error: Argument 1 passed to DOMNode::appendChild() must be an instance of DOMNode, boolean given, called in /in/ebVBR on line 6 and defined in /in/ebVBR on line 63
Process exited with code 255.
Output for 5.2.3 - 5.2.5
/bids_offersarray(4) {
[0]=>
object(DOMElement)#4 (0) {
}
[1]=>
object(DOMElement)#5 (0) {
}
[2]=>
object(DOMElement)#6 (0) {
}
[3]=>
object(DOMElement)#7 (0) {
}
}
Warning: DOMNode::appendChild() expects parameter 1 to be DOMNode, boolean given in /in/ebVBR on line 63
Fatal error: Call to a member function appendChild() on a non-object in /in/ebVBR on line 63
Process exited with code 255.
Output for 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.2
/bids_offersarray(4) {
[0]=>
object(DOMElement)#4 (0) {
}
[1]=>
object(DOMElement)#5 (0) {
}
[2]=>
object(DOMElement)#6 (0) {
}
[3]=>
object(DOMElement)#7 (0) {
}
}
<br />
<b>Warning</b>: DOMNode::appendChild() expects parameter 1 to be DOMNode, boolean given in <b>/in/ebVBR</b> on line <b>63</b><br />
<br />
<b>Fatal error</b>: Call to a member function appendChild() on a non-object in <b>/in/ebVBR</b> on line <b>63</b><br />
Process exited with code 255.
Output for 5.0.0 - 5.0.4
/bids_offersarray(4) {
[0]=>
object(DOMElement)#4 (0) {
}
[1]=>
object(DOMElement)#5 (0) {
}
[2]=>
object(DOMElement)#6 (0) {
}
[3]=>
object(DOMElement)#7 (0) {
}
}
<br />
<b>Warning</b>: appendChild() expects parameter 1 to be DOMNode, boolean given in <b>/in/ebVBR</b> on line <b>63</b><br />
<br />
<b>Fatal error</b>: Call to a member function appendChild() on a non-object in <b>/in/ebVBR</b> on line <b>63</b><br />
Process exited with code 255.
Output for 4.4.2 - 4.4.9
<br />
<b>Parse error</b>: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in <b>/in/ebVBR</b> on line <b>12</b><br />
Process exited with code 255.
<br />
<b>Parse error</b>: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in <b>/in/ebVBR</b> on line <b>12</b><br />
Process exited with code 255.
Output for 4.3.2 - 4.3.4
<br />
<b>Parse error</b>: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in <b>/in/ebVBR</b> on line <b>12</b><br />
Process exited with code 255.