2011-04-16 70 views
1

我想動態創建一些XML,我想知道如何將XMLElement添加到XMLElement?如何將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

我還沒有找到答案,我的問題。 我編寫了一個從SimpleXmlElement繼承的類,並添加了一個方法「addChildElement(XElement $ element)」。該方法在參數中使用XElement並遞歸添加它(及其子元素)。 我不知道這是否是最好的辦法,但它似乎對我來說工作得很好。 如果此功能出現問題,告訴我。 請注意,將xElement添加到xml後無法修改XElement,但我正在處理它。

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); 
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(); 

?> 
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>$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>