У меня есть этот код для создания и обновления файла 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>
Понял! Я адаптировал код из этого замечательного решения :
<?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-файл:
<?xml version="1.0"?> <site> <title lang="en"><![CDATA[Site Title]]></title> </site>
Спасибо Петаху
Вот моя версия этого класса, в которой есть быстрый метод 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 <>');
Вы также можете создать вспомогательную функцию для этого, если вы не хотите распространять 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; };
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> */
Вот мое совместное решение с добавлением ребенка с 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');