如何使用SimpleXmlElement编写CDATA?

发布于 2024-11-14 08:03:12 字数 607 浏览 2 评论 0原文

我有这段代码来创建和更新 xml 文件:

<?php
$xmlFile    = 'config.xml';
$xml        = new SimpleXmlElement('<site/>');
$xml->title = 'Site Title';
$xml->title->addAttribute('lang', 'en');
$xml->saveXML($xmlFile);
?>

这会生成以下 xml 文件:

<?xml version="1.0"?>
<site>
  <title lang="en">Site Title</title>
</site>

问题是:有没有办法使用此方法/技术添加 CDATA 来创建下面的 xml 代码?

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

I have this code to create and update xml file:

<?php
$xmlFile    = 'config.xml';
$xml        = new SimpleXmlElement('<site/>');
$xml->title = 'Site Title';
$xml->title->addAttribute('lang', 'en');
$xml->saveXML($xmlFile);
?>

This generates the following xml file:

<?xml version="1.0"?>
<site>
  <title lang="en">Site Title</title>
</site>

The question is: is there a way to add CDATA with this method/technique to create xml code below?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

半城柳色半声笛 2024-11-21 08:03:12

知道了!我改编了这个出色的解决方案 (存档版本):

    <?php
    
    // http://coffeerings.posterous.com/php-simplexml-and-cdata
    // https://web.archive.org/web/20110223233311/http://coffeerings.posterous.com/php-simplexml-and-cdata
    
    // Customized 'SimpleXMLElement' class.
    class SimpleXMLExtended extends SimpleXMLElement {
    
      // Create CDATA section custom function.
      public function addCData( $cdata_text ) {
        $node              = dom_import_simplexml( $this ); 
        $ownerDocumentNode = $node->ownerDocument;
        
        $node->appendChild( $ownerDocumentNode->createCDATASection( $cdata_text )); 
      }
    
    }
    
    // How to create the following example, below:
    // <?xml version="1.0"?>
    // <site>
    //   <title lang="en"><![CDATA[Site Title]]></title>
    // </site>
    
    /*
     * Instead of SimpleXMLElement:
     * $xml = new SimpleXMLElement( '<site/>' );
     * create from custom class, in this case, SimpleXMLExtended.
    */
    
    // Name of the XML file.
    $xmlFile    = 'config.xml';

    // <?xml version="1.0"?>
    // <site></site>
    // ^^^^^^^^^^^^^
    $xml        = new SimpleXMLExtended( '<site/>' );
    
    // Insert '<title><title>' into '<site></site>'.
    // <?xml version="1.0"?>
    // <site>
    //   <title></title>
    //   ^^^^^^^^^^^^^^^
    // </site>
    $xml->title = NULL; // VERY IMPORTANT! We need a node where to append.
    
    // CDATA section custom function.
    // <?xml version="1.0"?>
    // <site></site>
    // <title><![CDATA[Site Title]]></title>
    //        ^^^^^^^^^^^^^^^^^^^^^^
    // </site>
    $xml->title->addCData( 'Site Title' );
    
    // Add an attribute.
    // <?xml version="1.0"?>
    // <site></site>
    //   <title lang="en"><![CDATA[Site Title]]></title>
    //          ^^^^^^^^^^
    // </site>
    $xml->title->addAttribute( 'lang', 'en' );
    
    // Save.
    $xml->saveXML( $xmlFile );
    
    ?>

XML 文件,config.xml,生成:

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

谢谢 Petah ,希望有帮助!

Got it! I adapted the code from this great solution (archived version):

    <?php
    
    // http://coffeerings.posterous.com/php-simplexml-and-cdata
    // https://web.archive.org/web/20110223233311/http://coffeerings.posterous.com/php-simplexml-and-cdata
    
    // Customized 'SimpleXMLElement' class.
    class SimpleXMLExtended extends SimpleXMLElement {
    
      // Create CDATA section custom function.
      public function addCData( $cdata_text ) {
        $node              = dom_import_simplexml( $this ); 
        $ownerDocumentNode = $node->ownerDocument;
        
        $node->appendChild( $ownerDocumentNode->createCDATASection( $cdata_text )); 
      }
    
    }
    
    // How to create the following example, below:
    // <?xml version="1.0"?>
    // <site>
    //   <title lang="en"><![CDATA[Site Title]]></title>
    // </site>
    
    /*
     * Instead of SimpleXMLElement:
     * $xml = new SimpleXMLElement( '<site/>' );
     * create from custom class, in this case, SimpleXMLExtended.
    */
    
    // Name of the XML file.
    $xmlFile    = 'config.xml';

    // <?xml version="1.0"?>
    // <site></site>
    // ^^^^^^^^^^^^^
    $xml        = new SimpleXMLExtended( '<site/>' );
    
    // Insert '<title><title>' into '<site></site>'.
    // <?xml version="1.0"?>
    // <site>
    //   <title></title>
    //   ^^^^^^^^^^^^^^^
    // </site>
    $xml->title = NULL; // VERY IMPORTANT! We need a node where to append.
    
    // CDATA section custom function.
    // <?xml version="1.0"?>
    // <site></site>
    // <title><![CDATA[Site Title]]></title>
    //        ^^^^^^^^^^^^^^^^^^^^^^
    // </site>
    $xml->title->addCData( 'Site Title' );
    
    // Add an attribute.
    // <?xml version="1.0"?>
    // <site></site>
    //   <title lang="en"><![CDATA[Site Title]]></title>
    //          ^^^^^^^^^^
    // </site>
    $xml->title->addAttribute( 'lang', 'en' );
    
    // Save.
    $xml->saveXML( $xmlFile );
    
    ?>

XML file, config.xml, generated:

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

Thank you Petah, hope it helps!

我的奇迹 2024-11-21 08:03:12

这是我的此类版本,它具有快速 addChildWithCDATA 方法,基于 您的答案

    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;
  }
}

简单地使用它:

$node = new SimpleXMLElementExtended();
$node->addChildWithCDATA('title', 'Text that can contain any unsafe XML charachters like & and <>');

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 <>');
对不⑦ 2024-11-21 08:03:12

如果您不想扩展 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;
 };

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;
 };
み零 2024-11-21 08:03:12
    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>
   */
    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>
   */
古镇旧梦 2024-11-21 08:03:12

这是我的组合解决方案,使用 CDATA 添加子项或将 CDATA 添加到节点。

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

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');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文