How to write CDATA using SimpleXmlElement?

后端 未结 5 733
情话喂你
情话喂你 2020-11-27 15:08

I have this code to create and update xml file:

\');
$xml->title          


        
相关标签:
5条回答
  • 2020-11-27 15:54

    Got it! I adapted the code from this great solution:

    <?php
    // http://coffeerings.posterous.com/php-simplexml-and-cdata
    class SimpleXMLExtended extends SimpleXMLElement {
      public function addCData($cdata_text) {
        $node = dom_import_simplexml($this); 
        $no   = $node->ownerDocument; 
        $node->appendChild($no->createCDATASection($cdata_text)); 
      } 
    }
    
    $xmlFile    = 'config.xml';
    // instead of $xml = new SimpleXMLElement('<site/>');
    $xml        = new SimpleXMLExtended('<site/>');
    $xml->title = NULL; // VERY IMPORTANT! We need a node where to append
    $xml->title->addCData('Site Title');
    $xml->title->addAttribute('lang', 'en');
    $xml->saveXML($xmlFile);
    ?>
    

    XML file generated:

    <?xml version="1.0"?>
    <site>
      <title lang="en"><![CDATA[Site Title]]></title>
    </site>
    

    Thank you Petah

    0 讨论(0)
  • 2020-11-27 15:54

    You can also create a helper function for this, if you'd rather not extend SimpleXMLElement:

     /**
      * Adds a CDATA property to an XML document.
      *
      * @param string $name
      *   Name of property that should contain CDATA.
      * @param string $value
      *   Value that should be inserted into a CDATA child.
      * @param object $parent
      *   Element that the CDATA child should be attached too.
      */
     $add_cdata = function($name, $value, &$parent) {
       $child = $parent->addChild($name);
    
       if ($child !== NULL) {
         $child_node = dom_import_simplexml($child);
         $child_owner = $child_node->ownerDocument;
         $child_node->appendChild($child_owner->createCDATASection($value));
       }
    
       return $child;
     };
    
    0 讨论(0)
  • 2020-11-27 15:57
        class MySimpleXMLElement extends SimpleXMLElement{
    
            public function addChildWithCData($name , $value) {
                $new = parent::addChild($name);
                $base = dom_import_simplexml($new);
                $docOwner = $base->ownerDocument;
                $base->appendChild($docOwner->createCDATASection($value));
            }
    
        }
    
            $simpleXmlElemntObj = new MySimpleXMLElement('<site/>');
    
            /* USAGE */
    
            /* Standard */
            $simpleXmlElemntObj->addChild('Postcode','1111');
    
           /* With CDATA */
           $simpleXmlElemntObj->addChildWithCData('State','Processing');
    
    
        /* RESULT */
        /*
        <?xml version="1.0"?>
        <site>
            <Postcode>1111</Postcode>
            <State><![CDATA[Processing]]></State>
        </site>
       */
    
    0 讨论(0)
  • 2020-11-27 15:59

    Here's my version of this class that has a quick addChildWithCDATA method, based on your answer:

        Class SimpleXMLElementExtended extends SimpleXMLElement {
    
      /**
       * Adds a child with $value inside CDATA
       * @param unknown $name
       * @param unknown $value
       */
      public function addChildWithCDATA($name, $value = NULL) {
        $new_child = $this->addChild($name);
    
        if ($new_child !== NULL) {
          $node = dom_import_simplexml($new_child);
          $no   = $node->ownerDocument;
          $node->appendChild($no->createCDATASection($value));
        }
    
        return $new_child;
      }
    }
    

    Simply use it like that:

    $node = new SimpleXMLElementExtended();
    $node->addChildWithCDATA('title', 'Text that can contain any unsafe XML charachters like & and <>');
    
    0 讨论(0)
  • 2020-11-27 16:02

    Here is my combined solution with adding child with CDATA or adding CDATA to the node.

    class SimpleXMLElementExtended extends SimpleXMLElement
    {
        /**
        * Add value as CData to a given XML node
        *
        * @param SimpleXMLElement $node SimpleXMLElement object representing the child XML node
        * @param string $value A text to add as CData
        * @return void
        */
        private function addCDataToNode(SimpleXMLElement $node, $value = '')
        {
            if ($domElement = dom_import_simplexml($node))
            {
                $domOwner = $domElement->ownerDocument;
                $domElement->appendChild($domOwner->createCDATASection("{$value}"));
            }
        }
    
        /**
        * Add child node with value as CData
        *
        * @param string $name The child XML node name to add
        * @param string $value A text to add as CData
        * @return SimpleXMLElement
        */
        public function addChildWithCData($name = '', $value = '')
        {
            $newChild = parent::addChild($name);
            if ($value) $this->addCDataToNode($newChild, "{$value}");
            return $newChild;
        }
    
        /**
        * Add value as CData to the current XML node 
        *
        * @param string $value A text to add as CData
        * @return void
        */
        public function addCData($value = '')
        {
            $this->addCDataToNode($this, "{$value}");
        }
    }
    
    // Usage example:
    
    $xml_doc = '<?xml version="1.0" encoding="utf-8"?>
    <offers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1">
    </offers>';
    
    $xml = new SimpleXMLElementExtended($xml_doc);
    
    $offer = $xml->addChild('o');
    $offer->addAttribute('id', $product->product_id);
    $offer->addAttribute('url', 'some url');
    
    $cat = $offer->addChildWithCData('cat', 'Category description as CDATA');
    
    // or
    
    $cat = $offer->addChild('cat');
    $cat->addCData('Category description as CDATA');
    
    0 讨论(0)
提交回复
热议问题