擴大關接受的答案中我創建了一個靜態方法更多來自C#的XElement感覺。它還在添加子XElement節點時複製屬性。
class XElement extends SimpleXMLElement
{
/**
* Add an XElement to an XElement.
*
* @param XElement $element A SimpleXmlElement
*
* @return void
*/
public function add(XElement $element)
{
// TODO Handle namespaces
$addedElement = $this->addChild($element->getName(), (string)$element);
$this->_copyAttributes($element, $addedElement);
foreach ($element->children() as $node) {
$addedElement->add($node);
}
}
private function _copyAttributes($from, $to)
{
foreach ($from->attributes() as $n => $v) {
$to->addAttribute($n, $v);
}
}
public static function Node(string $name, $content, $attributes = null)
{
$content_type = gettype($content);
$element = null;
if ($content_type == 'string') {
$element = new XElement("<$name>$content</$name>");
} else {
if (substr($name, 0, 1) === "<") {
$element = new XElement($name);
} else {
$element = new XElement("<$name />");
}
if ($content_type == 'object' && get_class($content) == 'XElement') {
$element->add($content);
} else if ($content_type == 'array') {
foreach ($content as $c) {
$element->add($c);
}
}
}
if (!empty($attributes)) {
foreach ($attributes as $n => $v) {
$element->addAttribute($n, $v);
}
}
return $element;
}
}
要使用:
//auto close tags, add content text
$xml = XElement::Node('cXML', 'nothing');
//nested elements
$xml = XElement::Node('cXML',
XElement::Node('Header',
XElement::Node('Data', 'Your Text Here')
)
);
//attributes
$xml = XElement::Node('cXML',
XElement::Node('Header', '', ['type' => 'no_data'])
);
//multiple nodes (sibling nodes)
$header = XElement::Node('Header', '', ['type' => 'no_data']);
$request = XElement::Node('Request',
XElement::Node('Order',
//inline array
[
XElement::Node('Item',
XElement::Node('Qty', '1')
),
XElement::Node('Item',
XElement::Node('Qty', '2')
),
]
),
['type' => 'data']
);
$nodes = [ $header, $request ];
$xml = XElement::Node('cXML', $nodes);
輸出:
<!-- auto close tags, add content text -->
<?xml version="1.0"?>
<cXML>nothing</cXML>
<!-- nested elements -->
<?xml version="1.0"?>
<cXML>
<Header>
<Data>Your Text Here</Data>
</Header>
</cXML>
<!-- attributes -->
<?xml version="1.0"?>
<cXML>
<Header type="no_data"/>
</cXML>
<!-- multiple nodes (sibling nodes) -->
<?xml version="1.0"?>
<cXML>
<Header type="no_data"/>
<Request type="data">
<Order>
<Item>
<Qty>1</Qty>
</Item>
<Item>
<Qty>2</Qty>
</Item>
</Order>
</Request>
</cXML>