• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • SimpleXMLElement::addChild()

    (PHP 5 >= 5.1.3, PHP 7)

    Adds a child element to the XML node

    说明

    publicSimpleXMLElement::addChild(string $name[,string $value[,string $namespace]]): SimpleXMLElement

    Adds a child element to the node and returns a SimpleXMLElement of the child.

    参数

    $name

    The name of the child element to add.

    $value

    If specified, the value of the child element.

    $namespace

    If specified, the namespace to which the child element belongs.

    返回值

    TheaddChildmethod returns a SimpleXMLElement object representing the child added to the XML node.

    范例

    Note:

    Listed examples may includeexample.php, which refers to the XML string found in the first example of the basic usage guide.

    Example #1 Add attributes and children to a SimpleXML element

    <?php
    include 'example.php';
    $sxe = new SimpleXMLElement($xmlstr);
    $sxe->addAttribute('type', 'documentary');
    $movie = $sxe->addChild('movie');
    $movie->addChild('title', 'PHP2: More Parser Stories');
    $movie->addChild('plot', 'This is all about the people who make it work.');
    $characters = $movie->addChild('characters');
    $character  = $characters->addChild('character');
    $character->addChild('name', 'Mr. Parser');
    $character->addChild('actor', 'John Doe');
    $rating = $movie->addChild('rating', '5');
    $rating->addAttribute('type', 'stars');
     
    echo $sxe->asXML();
    ?>
    

    以上例程的输出类似于:

    <?xml version="1.0" standalone="yes"?>
    <movies type="documentary">
     <movie>
      <title>PHP: Behind the Parser</title>
      <characters>
       <character>
        <name>Ms. Coder</name>
        <actor>Onlivia Actora</actor>
       </character>
       <character>
        <name>Mr. Coder</name>
        <actor>El Act&#xD3;r</actor>
       </character>
      </characters>
      <plot>
       So, this language. It's like, a programming language. Or is it a
       scripting language? All is revealed in this thrilling horror spoof
       of a documentary.
      </plot>
      <great-lines>
       <line>PHP solves all my web problems</line>
      </great-lines>
      <rating type="thumbs">7</rating>
      <rating type="stars">5</rating>
     </movie>
     <movie>
      <title>PHP2: More Parser Stories</title>
      <plot>This is all about the people who make it work.</plot>
      <characters>
       <character>
        <name>Mr. Parser</name>
        <actor>John Doe</actor>
       </character>
      </characters>
      <rating type="stars">5</rating>
     </movie>
    </movies>
    

    参见

    • SimpleXMLElement::addAttribute() Adds an attribute to the SimpleXML element
    • Basic SimpleXML usage
    To complete Volker Grabsch's comment, stating :
    "Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&"."
    To work around that problem, you can use direct property assignment such as :
    <?php
    $xmlelement->value = 'my value < > &';
    // results in <value>my value &lt; &gt; &amp;</value>
    ?>
    instead of doing :
    <?php
    $xmlelement->addChild('value', 'my value < > &');
    // results in <value>my value &lt; &gt; &</value> (invalid XML)
    ?>
    See also: http://stackoverflow.com/questions/552957 (Rationale behind SimpleXMLElement's handling of text values in addChild and addAttribute)
    HTH
    Here is a class with more functions for SimpleXMLElement :
    <?php
    /**
     *
     * Extension for SimpleXMLElement
     * @author Alexandre FERAUD
     *
     */
    class ExSimpleXMLElement extends SimpleXMLElement
    {
      /**
       * Add CDATA text in a node
       * @param string $cdata_text The CDATA value to add
       */
     private function addCData($cdata_text)
     {
      $node= dom_import_simplexml($this);
      $no = $node->ownerDocument;
      $node->appendChild($no->createCDATASection($cdata_text));
     }
     /**
      * Create a child with CDATA value
      * @param string $name The name of the child element to add.
      * @param string $cdata_text The CDATA value of the child element.
      */
      public function addChildCData($name,$cdata_text)
      {
        $child = $this->addChild($name);
        $child->addCData($cdata_text);
      }
      /**
       * Add SimpleXMLElement code into a SimpleXMLElement
       * @param SimpleXMLElement $append
       */
      public function appendXML($append)
      {
        if ($append) {
          if (strlen(trim((string) $append))==0) {
            $xml = $this->addChild($append->getName());
            foreach($append->children() as $child) {
              $xml->appendXML($child);
            }
          } else {
            $xml = $this->addChild($append->getName(), (string) $append);
          }
          foreach($append->attributes() as $n => $v) {
            $xml->addAttribute($n, $v);
          }
        }
      }
    }
    ?>
    
    In the docs for google sitemaps it is required an element for mobile sitemaps that looks like this: <mobile:mobile/>
    I used some time to figure out how to make it, but it is quite simple when understood.
    $mobile_schema = 'http://www.google.com/schemas/sitemap-mobile/1.0';
    //Create root element
    $xml_mobile = new SimpleXMLElement('
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:mobile="'.$mobile_schema.'"></urlset>
    ');
    //Add required children
    $url_mobile = $xml_b_list_mobile->addChild('url');
    $url_mobile->addChild('loc', 'your-mobile-site-url');
    $url_mobile->addChild('mobile:mobile', null, $mobile_schema);
    For this to work properly the attribute xmlns:mobile must be set in the root node, and then used as namespace(third argument) when creating the mobile:mobile child with null as value.
    Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&".
    So addChild() is unsuited to handle user-defined input!
    Instead, you will have to replace all "&" with "&amp;" before calling addChild().
    Or, use htmlspecialchars() which also replaces other characters, but won't do any harm as addChild() won't replace those again.
    Want to continue the ampersand (&) chain problem.
    Sometimes, you would want to assign (=) addChild.
    This trick will helps you to do this.
    <?php
    $webOrders = new SimpleXMLElement('<?xml version="1.0"?><WebOrders></WebOrders>');
    $webOrder = $webOrders->addChild('WebOrder');
    $product = $webOrder->addChild('Product');
    $product[0] = 'T&M';
    $product->addAttribute('price', 19.99);
    $product->addAttribute('qty', 2);
    var_dump($webOrders->asXML());
    ?>
    OUTPUT would be:
    <?xml version="1.0" encoding="UTF-8"?>
    <WebOrders>
      <WebOrder>
        <Product price="19.99" qty="2">T&amp;M</Product>
      </WebOrder>
    </WebOrders>
    Here's my solution for creating XML from Multidimensional Array. 
    <?php
    //DATA 
        $xmlDAta = array(
          array(
            "name" => "nameVal",
            "value" => "valVal",
            "css"  => "cssVal"
          ),
          array(
            "name" => "name1Val",
            "value" => "val1Val",
            "css"  => "css1Val"
          ),
          "tname" => array(
            array(
              "iTname"  => "iTname",
              "iTname2" => "iTname1",
              "iTname2" => "iTname2",
              "iTbname3" => array(
                "iiTbname" => "tbName",
                "iiTbname1" => "tbName1",
              ),
            ),
          ),
          "tdata" => "otheerDAta"
        );
      /**
       * Create XML using string or array
       *
       * @param mixed $data input data
       * @param SimpleXMLElement $xml
       * @param string $child name of first level child
       *
       * @return adding Xml formated data into SimpleXmlElement
       */
    function data2XML(array $data, SimpleXMLElement $xml, $child = "items")
      {
        foreach($data as $key => $val) {
          if(is_array($val)) {
            if(is_numeric($key)) {
              $node = $xml->addChild($child);
              $nodes = $node->getName($child);
            } else {
              $node = $xml->addChild($key);
              $nodes = $node->getName($key);
            }
            $node->addChild($nodes, self::data2Xml($val, $node));
          } else {
            $xml->addChild($key, $val);
          }
        }
      }
    //Use 
        $xml  = new SimpleXMLElement("<root/>");
        Util::data2XML($xmlDAta, $xml, "Items");
    ?>
    
    Be aware that simply because you can <?php $dom->addChild();?> doesn't mean your XML is valid under simple XML itself:
    <?php
    $dom=simplexml_load_string("<test></test>");
    $dom->addChild("3D","1,2,3");
    $xml=$dom->asXML();
    echo $xml;
    /* echos:
    <?xml version="1.0"?>
    <test><3D>1,2,3</3D></test>
    */
    $dom=simplexml_load_string($xml);
    /*
    generates a whole lots of warnings,
    and refuses to create an object.
    */
    ?>
    Same in PHP 5.3 and 5.4
    This method returns a reference to the specific SimpleXMLElement.
    If you use:
    <?php
      $xml= new SimpleXMLElement('<root></root>');
      $xml->father['name']= 'Fathers name'; // creates automatically a father tag with attribute name
      $son= $xml->father->addChild('son'); // uses the first father tag
      $son['name']= 'first son';
      $otherSon= $xml->father->addChild('son'); // uses the first father tag but now, in a second son tag
      $otherSon['name']= 'second son';
      
      echo htmlentities($xml->asXML());
    ?>
    The result will be
    <root>
      <father>
        <son name='first son' />
        <son name='second son' />
      </father>
    </root>
    So, once you change something to the just added child, you are actually accessing the element inside the SimpleXMLElement as a reference.
    If you're looking for a way to append children you may be interested in this:
    <?php
    $x = new SimpleXMLElement('<root name="toplevel"></root>');
    $f1 = new SimpleXMLElement('<child pos="1">alpha</child>');
    $f2 = new SimpleXMLElement('<child pos="2">beta</child>');
    $f3 = new SimpleXMLElement('<child pos="3">gamma</child>');
    $x->{$f1->getName()} = $f1;
    $x->{$f2->getName()}[] = $f2;
    $x->{$f3->getName()}[] = $f3;
    echo 'count child=',$x->count(),"\n";
    echo $x->asXML();
    foreach ( $x->children() as $foo )
    {
      var_dump($foo);
    }
    ?>
    
    <?php
    class MySimpleXMLElement extends SimpleXMLElement
    {
      /**
       * Add SimpleXMLElement code into a SimpleXMLElement
       *
       * @param SimpleXMLElement $append
       */
      public function appendXML($append)
      {
        if ($append) {
          if (strlen(trim((string)$append)) == 0) {
            $xml = $this->addChild($append->getName());
          } else {
            $xml = $this->addChild($append->getName(), (string)$append);
          }
          foreach ($append->children() as $child) {
            $xml->appendXML($child);
          }
          foreach ($append->attributes() as $n => $v) {
            $xml->addAttribute($n, $v);
          }
        }
      }
    }
    ?>