2010-08-06 18 views
8

Estoy usando simpleXML para agregar un nodo hijo dentro de uno de mis documentos XML ... cuando hago una print_r en mi objeto simpleXML, el < todavía se muestra como un < en la fuente de la vista. Sin embargo, después de guardar este objeto de nuevo a XML utilizando DOMDocument, la < se convierte en &lt; y la > se convierte en &gt;Cómo evitar que DOMDocument guarde <as & lt

Cualquier ideas sobre cómo cambiar este comportamiento? Intenté agregar dom->substituteEntities = false;, pero esto no sirvió.

//Convert SimpleXML element to DOM and save 
    $dom = new DOMDocument('1.0'); 
    $dom->preserveWhiteSpace = false; 
    $dom->formatOutput = false; 
    $dom->substituteEntities = false; 
    $dom->loadXML($xml->asXML()); 
    $dom->save($filename); 

Aquí es donde estoy usando el <:

$new_hint = '<![CDATA[' . $value[0] . ']]>';    
$PrintQuestion->content->multichoice->feedback->hint->Passage->Paragraph->addChild('TextFragment', $new_hint); 

El problema, es que estoy usando XML sencilla para iterar a través de ciertos nodos del documento XML, y si un atributo coincide con una identificador dado, se agrega un nodo secundario específico con CDATA. A continuación, después de todo processsing, ahorro el XML de nuevo a archivo usando DOMDocument, que es donde el < se convierte en & lt, etc.

Aquí hay un enlace a toda mi archivo de clase, para que pueda tener una mejor idea de lo que estoy tratando de lograr Específicamente, consulte el método hint_insert() en la parte inferior.

http://pastie.org/1079562

+0
+0

Estoy tratando de lograr agregar una etiqueta CDATA ... Revisar la publicación original para el código actualizado – ThinkingInBits

+0

¡Gracias por votar! La etiqueta CDATA es necesaria (a menos que escape) en xml cuando tiene '<' and '>' dentro de un nodo. Igual que XHTML ... – xandercoded

Respuesta

10

SimpleXML y php5 DOM module utilizan la misma representación interna del documento (facilitado por libxml). Puede alternar entre ambas apis sin tener que volver a analizar el documento a través de simplexml_import_dom() y dom_import_simplexml().
I.e.Si realmente desea/debe realizar la iteración con la aplicación SimpleXML una vez que haya encontrado su elemento, puede cambiar a la API DOM y al create the CData section dentro del mismo documento .

<?php 
$doc = new SimpleXMLElement('<a> 
    <b id="id1">a</b> 
    <b id="id2">b</b> 
    <b id="id3">c</b> 
</a>'); 


foreach($doc->xpath('b[@id="id2"]') as $b) { 
    $b = dom_import_simplexml($b); 
    $cdata = $b->ownerDocument->createCDataSection('0<>1'); 
    $b->appendChild($cdata); 
    unset($b); 
} 

echo $doc->asxml(); 

impresiones

<?xml version="1.0"?> 
<a> 
    <b id="id1">a</b> 
    <b id="id2">b<![CDATA[0<>1]]></b> 
    <b id="id3">c</b> 
</a> 
+0

GRACIAS. Esta es la información que necesitaba. No me di cuenta de que podía usar ambos de manera intercambiable. – ThinkingInBits

+0

¿La configuración $ b = dom_import_simplexml ($ b) arruinará la iteración? – ThinkingInBits

+0

Funciona, pero no entiendo al 100% por qué: P – ThinkingInBits

3

El problema es que es muy probable que la adición como una cadena, en lugar de como un elemento.

Así, en lugar de:

$simple->addChild('foo', '<something/>'); 

los cuales serán tratados como texto:

$child = $simple->addChild('foo'); 
$child->addChild('something'); 

No se puede tener un literal < en el cuerpo del documento XML a menos que sea la apertura de una etiqueta.

Editar: Después de lo que usted describe en los comentarios, creo que lo que busca es:

DomDocument::createCDatatSection()

$child = $dom->createCDataSection('your <cdata> body '); 
$dom->appendChild($child); 

Edit2: Después de leer su edición, sólo hay una cosa que puedo Diga:

You're doing it wrong... No puede agregar elementos como un valor de cadena para otro elemento. Lo siento, simplemente no puedes. Es por eso que está escapando cosas, porque DOM y SimpleXML están ahí para asegurarse de que siempre cree XML válido. Es necesario crear el elemento como un objeto ... Por lo tanto, si desea crear el niño CDATA, que tendría que hacer algo como esto:

$child = $PrintQuestion.....->addChild('TextFragment'); 
$domNode = dom_import_simplexml($child); 
$cdata = $domNode->ownerDocument->createCDataSection($value[0]); 
$domNode->appendChild($cdata); 

Eso es todo lo que debería ser la de que ...

+0

Es la apertura y el cierre de una etiqueta CDATA que me está dando el problema ... Consulte la publicación original. – ThinkingInBits

+0

@ThinkingInBits: Vea la edición – ircmaxell

+0

Esta fue la respuesta correcta también, simplemente no lo entendí en ese momento. Votado, gracias. – ThinkingInBits

Cuestiones relacionadas