我想动态创建一些XML,我想知道如何将XMLElement添加到XMLElement中?
这是我的代码:
$table = new SimpleXMLElement("<table></table>");
$tableRow = new SimpleXMLElement("<tr></tr>");
$count = count($this->dataSource->columns);
for ($i = 0; $i < $count; $i++)
{
$tableRow->addChild("<th></th>","Hi!")
}
$table->addChild($tableRow); // Not good, but this is what I want to do.
答案 0 :(得分:1)
看看这个:Add Children with SimpleXML
示例:
<?php
$xml = <<<XML
<books>
<book title="Fahrenheit 451" author="Ray Bradbury"/>
<book title="Stranger in a Strange Land" author="Robert Heinlein"/>
</books>
XML;
$sxe = new SimpleXMLElement($xml);
$new_book = $sxe->addChild('book');
$new_book->addAttribute('title', '1984');
$new_book->addAttribute('author', 'George Orwell');
echo $sxe->asXML();
?>
答案 1 :(得分:0)
我没有找到问题的答案。 我编写了一个继承自SimpleXmlElement的类,并添加了一个方法“addChildElement(XElement $ element)”。该方法在参数中使用XElement并递归地添加它(及其子)。 我不知道这是否是最好的方法,但它似乎对我来说非常好。 告诉我这个功能是否有问题。 请注意,在将XElement添加到xml后,您无法修改它,但我正在处理它。
class XElement extends SimpleXMLElement
{
/**
* Add an XElement to an XElement.
* @param XElement $element
* @return void
*/
public function addChildElement(XElement $element)
{
// TODO Handle namespaces
$addedElement = $this->addChild($element->getName(), (string)$element);
foreach ($element->children() as $node)
{
$addedElement->addChildElement($node);
}
}
}
使用方法:
$tableRow = new XElement("<tr></tr>");
$asd = new XElement("<tr2></tr2>");
$asd2 = new XElement("<tr3></tr3>");
$asd->addChildElement($asd2);
$tableRow->addChildElement($asd);
这不会奏效,但我正在努力:
$tableRow = new XElement("<tr></tr>");
$asd = new XElement("<tr2></tr2>");
$asd2 = new XElement("<tr3></tr3>");
$tableRow->addChildElement($asd);
$asd->addChildElement($asd2);
答案 2 :(得分:0)
扩展已接受的答案我为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 />");
$element[0] = $content;
} 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>