Reputation: 674
I'm generating an XML file via PHP and I'm doing it this way:
$dom = new DOMDocument();
$root = $dom->createElement('Root');
...
// some node definitions here etc
$root->appendChild($product);
$root->appendChild($quantity);
$root->appendChild($measureUnit);
$root->appendChild($lineNumber);
...
$dom->appendChild($root);
$dom->save( '/some/dir/some-name.xml');
It all works well until I encountered some problem, when I get to the part that I needed to append lets say N
child nodes. This meant that I would be calling the function appendChild()
'N'
times too - and that resulted on a very long php script which is a little hard to maintain.
I know we can split the main script on smaller files for better maintenance but are there better ways to just 'chain' the 'appendChild' calls so it would save as a lot of written lines or is there a somewhat magic function such as 'appendChildren' available?
This is my first time using the DOMDocument()
class, I hope someone can shed me some light.
Thank you
Upvotes: 0
Views: 246
Reputation: 19482
You can nest the DOMDocument::createElement()
into DOMNode::appendChild()
calls and chain child nodes or text content assignments.
Since PHP 8.0 DOMNode::append()
can be used to append multiple nodes and strings.
$document = new DOMDocument();
// nest createElement inside appendChild
$document->appendChild(
// store node in variable
$root = $document->createElement('root')
);
// chain textContent assignment to appendChild
$root
->appendChild($document->createElement('product'))
->textContent = 'Example';
// use append to add multiple nodes
$root->append(
$product = $document->createElement('measureUnit'),
$quantity = $document->createElement('quantity'),
);
$product->textContent = 'cm';
$quantity->textContent = '42';
$document->formatOutput= true;
echo $document->saveXML();
Output:
<?xml version="1.0"?>
<root>
<product>Example</product>
<measureUnit>cm</measureUnit>
<quantity>42</quantity>
</root>
I am using an interface for reusable and maintainable parts, usually:
interface XMLAppendable {
public function appendTo(DOMElement $parent): void;
}
class YourXMLPart implements XMLAppendable {
private $_product;
private $_unit;
private $_quantity;
public function __construct(string $product, string $unit, int $quantity) {
$this->_product = $product;
$this->_unit = $unit;
$this->_quantity = $quantity;
}
public function appendTo(DOMElement $parent): void {
$document = $parent->ownerDocument;
$parent
->appendChild($document->createElement('product'))
->textContent = $this->_product;
$parent
->appendChild($document->createElement('measureUnit'))
->textContent = $this->_unit;
$parent
->appendChild($document->createElement('quantity'))
->textContent = $this->_quantity;
}
}
$document = new DOMDocument();
// nest createElement inside appendChild
$document->appendChild(
// store node in variable
$root = $document->createElement('root')
);
$part = new YourXMLPart('Example', 'cm', 42);
$part->appendTo($root);
$document->formatOutput= true;
echo $document->saveXML();
Upvotes: 1