new - simplexml_load_file php 7
¿Cómo escribir CDATA usando SimpleXmlElement? (5)
¡Lo tengo! Adapte el código de esta gran solución :
<?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);
?>
Archivo XML generado:
<?xml version="1.0"?>
<site>
<title lang="en"><![CDATA[Site Title]]></title>
</site>
Gracias Petah
Tengo este código para crear y actualizar el archivo xml:
<?php
$xmlFile = ''config.xml'';
$xml = new SimpleXmlElement(''<site/>'');
$xml->title = ''Site Title'';
$xml->title->addAttribute(''lang'', ''en'');
$xml->saveXML($xmlFile);
?>
Esto genera el siguiente archivo xml:
<?xml version="1.0"?>
<site>
<title lang="en">Site Title</title>
</site>
La pregunta es: ¿hay alguna manera de agregar CDATA con este método / técnica para crear código xml a continuación?
<?xml version="1.0"?>
<site>
<title lang="en"><![CDATA[Site Title]]></title>
</site>
Aquí está mi solución combinada con agregar hijos con CDATA o agregar CDATA al nodo.
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'');
Aquí está mi versión de esta clase que tiene un método rápido addChildWithCDATA, basado en su respuesta :
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;
}
}
Simplemente úsalo así:
$node = new SimpleXMLElementExtended();
$node->addChildWithCDATA(''title'', ''Text that can contain any unsafe XML charachters like & and <>'');
También puede crear una función auxiliar para esto, si prefiere no extender 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>
*/