2011-12-23 12 views
41

Ecco i codici:PHP XML come formato di output bello

$doc = new DomDocument('1.0'); 
// create root node 
$root = $doc->createElement('root'); 
$root = $doc->appendChild($root); 
$signed_values = array('a' => 'eee', 'b' => 'sd', 'c' => 'df'); 
// process one row at a time 
foreach ($signed_values as $key => $val) { 
    // add node for each row 
    $occ = $doc->createElement('error'); 
    $occ = $root->appendChild($occ); 
    // add a child node for each field 
    foreach ($signed_values as $fieldname => $fieldvalue) { 
     $child = $doc->createElement($fieldname); 
     $child = $occ->appendChild($child); 
     $value = $doc->createTextNode($fieldvalue); 
     $value = $child->appendChild($value); 
    } 
} 
// get completed xml document 
$xml_string = $doc->saveXML() ; 
echo $xml_string; 

Se lo stampo nel browser non ottengo bella struttura XML come

<xml> \n tab <child> etc. 

ottengo solo

<xml><child>ee</child></xml> 

E voglio essere utf-8 Come è possibile fare tutto questo?

+0

Circa il problema utf-8, è sufficiente aggiungere all'oggetto come un secondo parametro come '$ doc = new DOMDocument ("1.0", "UTF-8");' – Thielicious

risposta

73

Si può provare a fare questo:

... 
// get completed xml document 
$doc->preserveWhiteSpace = false; 
$doc->formatOutput = true; 
$xml_string = $doc->saveXML(); 
echo $xml_string; 

Si possono effettuare impostare questi parametri a destra dopo aver creato il DOMDocument così:

$doc = new DomDocument('1.0'); 
$doc->preserveWhiteSpace = false; 
$doc->formatOutput = true; 

Questo è probabilmente più concisa. Uscita in entrambi i casi è (Demo):

<?xml version="1.0"?> 
<root> 
    <error> 
    <a>eee</a> 
    <b>sd</b> 
    <c>df</c> 
    </error> 
    <error> 
    <a>eee</a> 
    <b>sd</b> 
    <c>df</c> 
    </error> 
    <error> 
    <a>eee</a> 
    <b>sd</b> 
    <c>df</c> 
    </error> 
</root> 

Non sono a conoscenza come cambiare il carattere di indentazione (s) con DOMDocument. Si potrebbe post-process l'XML con una line-by-line espressioni regolari base sostituzione (per esempio con preg_replace):

$xml_string = preg_replace('/(?:^|\G) /um', "\t", $xml_string); 

In alternativa, c'è il tidy extension with tidy_repair_string che può tranquillamente i dati XML di stampa pure. È possibile specificare i livelli di indentazione con esso, tuttavia l'ordine non emetterà mai le tabulazioni.

tidy_repair_string($xml_string, ['input-xml'=> 1, 'indent' => 1, 'wrap' => 0]); 
+0

correlati: [* Debug un Oggetto DOMDocument in PHP *] (http://stackoverflow.com/q/684227/367456) per una forma più controllata di stampa XML. – hakre

+0

Correlati: [* Conversione di rientro con preg_replace (senza callback) *] (http://stackoverflow.com/q/8616594/367456) – hakre

+0

Ho scoperto che * "È possibile impostare questi parametri subito dopo aver creato anche il DOMDocument "* non è una grande idea se si usa' saveXML' mentre lo si elabora/si confronta con un altro documento perché può portare a risultati imprevisti. È meglio formattare l'output prima che sia necessario l'output. –

3

Due diverse edizioni qui:

  • impostare gli attributi formatOutput e preserveWhiteSpace a TRUE per generare in formato XML:

    $doc->formatOutput = TRUE; 
    $doc->preserveWhiteSpace = TRUE; 
    
  • Molti browser web (vale a dire Internet Explorer e Firefox) formatta XML quando lo visualizzano. Usa la funzione Visualizza sorgente o un normale editor di testo per ispezionare l'output.


Vedi anche xmlEncoding e encoding.

+1

'preserveWhiteSpace = TRUE' può essere d'intralcio quando si stampa bene con' DOMDocument' - solo FYI, non con l'esempio dato in questione, ma se si caricano da file esistenti che hanno effettivamente dei textnode di spazi bianchi. – hakre

+0

@hakre Perché 'preserveWhiteSpace = TRUE' funziona bene con XML, ma non funziona con HTML? – Yang

+0

Per consentire al browser di formattarlo, è necessario impostare un tipo MIME corretto. Ad esempio con: intestazione ('Content-type: text/xml'); – Den

20

Con un oggetto SimpleXML, si può semplicemente

$domxml = new DOMDocument('1.0'); 
$domxml->preserveWhiteSpace = false; 
$domxml->formatOutput = true; 
/* @var $xml SimpleXMLElement */ 
$domxml->loadXML($xml->asXML()); 
$domxml->save($newfile); 

$xml è l'oggetto SimpleXML

Così allora si SimpleXML puoi essere salvato come un nuovo file specificato da $newfile

+0

Si dice SimpleXML, ma si sta utilizzando un DOMDocument ... – quickshiftin

+0

@quickshiftin - I dati di input sono un'istanza di 'SimpleXMLElement'. Modificherò la risposta per renderla più ovvia. In ogni caso, sono d'accordo sul fatto che ciò che alimentate con 'DOMDocument' è in realtà irrilevante. –

1

Si tratta di un leggero variazione del tema di cui sopra ma sto mettendo qui nel caso in cui altri lo colpiscano e non riescano a dare un senso a questo ... come ho fatto io.

Quando si utilizza saveXML(), preserveWhiteSpace nel documento DOM di destinazione non si applica ai nodi importati (come in PHP 5.6).

Si consideri il seguente codice:

$dom = new DOMDocument();        //create a document 
$dom->preserveWhiteSpace = false;      //disable whitespace preservation 
$dom->formatOutput = true;        //pretty print output 
$documentElement = $dom->createElement("Entry");  //create a node 
$dom->appendChild ($documentElement);     //append it 
$message = new DOMDocument();       //create another document 
$message->loadXML($messageXMLtext);      //populate the new document from XML text 
$node=$dom->importNode($message->documentElement,true); //import the new document content to a new node in the original document 
$documentElement->appendChild($node);     //append the new node to the document Element 
$dom->saveXML($dom->documentElement);     //print the original document 

In questo contesto, la dichiarazione $dom->saveXML(); sarà NON abbastanza stampare il contenuto importato da $ messaggio, ma il contenuto originariamente nel $ dom sarà abbastanza stampata.

Al fine di ottenere abbastanza stampa per l'intero documento $ dom, la linea:

$message->preserveWhiteSpace = false; 

devono essere inclusi dopo la linea di $message = new DOMDocument(); - vale a dire. il/i documento/i da cui vengono importati i nodi devono inoltre avere preserveWhiteSpace = false.

9
<?php 

$xml = $argv[1]; 

$dom = new DOMDocument(); 

// Initial block (must before load xml string) 
$dom->preserveWhiteSpace = false; 
$dom->formatOutput = true; 
// End initial block 

$dom->loadXML($xml); 
$out = $dom->saveXML(); 

print_R($out); 
+1

potresti aggiungere una spiegazione? – Robert

+0

set formatOutput = true & preserveWhiteSpace = false, prima di caricare la stringa xml, altrimenti non ha alcun effetto --- se riesci a capire il mio inglese, oh, sei un genio !!! – sigkill

1
// ##### IN SUMMARY ##### 

$xmlFilepath = 'test.xml'; 
echoFormattedXML($xmlFilepath); 

/* 
* echo xml in source format 
*/ 
function echoFormattedXML($xmlFilepath) { 
    header('Content-Type: text/xml'); // to show source, not execute the xml 
    echo formatXML($xmlFilepath); // format the xml to make it readable 
} // echoFormattedXML 

/* 
* format xml so it can be easily read but will use more disk space 
*/ 
function formatXML($xmlFilepath) { 
    $loadxml = simplexml_load_file($xmlFilepath); 

    $dom = new DOMDocument('1.0'); 
    $dom->preserveWhiteSpace = false; 
    $dom->formatOutput = true; 
    $dom->loadXML($loadxml->asXML()); 
    $formatxml = new SimpleXMLElement($dom->saveXML()); 
    //$formatxml->saveXML("testF.xml"); // save as file 

    return $formatxml->saveXML(); 
} // formatXML 
+0

potenziato, perché questa risposta contiene un esempio completo! – baris1892

0

provato tutte le risposte, ma nessuno ha funzionato. Forse è perché sto appendendo e rimuovendo childs prima di salvare l'XML. Dopo molte ricerche su google trovate this comment nella documentazione php. Ho solo dovuto ricaricare l'XML risultante per farlo funzionare.

$outXML = $xml->saveXML(); 
$xml = new DOMDocument(); 
$xml->preserveWhiteSpace = false; 
$xml->formatOutput = true; 
$xml->loadXML($outXML); 
$outXML = $xml->saveXML();