2011-11-17 15 views
8

Ho un file XML che sembra qualcosa di simile:Come cambio i nomi dei tag XML con PHP?

<product> 
<modelNumber>Data</modelNumber> 
<salePrice>Data</salePrice> 
</product> 
<product> 
<modelNumber>Data</modelNumber> 
<salePrice>Data</salePrice> 
</product> 

C'è un modo semplice per modificare i nomi dei tag, a qualcosa di diverso, come modello, il prezzo.

In sostanza, ho un sacco di file XML contenenti dati simili, ma in diversi formati, quindi sto cercando un modo semplice per analizzare il file XML, modificare determinati nomi di tag e scrivere un nuovo file XML con il cambiato i nomi dei tag.

+0

È il vostro XML volutamente malformato? – kapa

+0

I file sono forniti da più fonti - i nomi dei tag non sono controllati da me. –

+0

Quindi errori come ' Dati' (tag di chiusura/chiusura diversi) sono normali? Perché allora non sarai in grado di analizzare questo documento con un parser XML (come il DOM PHP). – kapa

risposta

6

funzione Next farà il trucco:

/** 
* @param $xml string Your XML 
* @param $old string Name of the old tag 
* @param $new string Name of the new tag 
* @return string New XML 
*/ 
function renameTags($xml, $old, $new) 
{ 
    $dom = new DOMDocument(); 
    $dom->loadXML($xml); 

    $nodes = $dom->getElementsByTagName($old); 
    $toRemove = array(); 
    foreach ($nodes as $node) 
    { 
     $newNode = $dom->createElement($new); 
     foreach ($node->attributes as $attribute) 
     { 
      $newNode->setAttribute($attribute->name, $attribute->value); 
     } 

     foreach ($node->childNodes as $child) 
     { 
      $newNode->appendChild($node->removeChild($child)); 
     } 

     $node->parentNode->appendChild($newNode); 
     $toRemove[] = $node; 
    } 

    foreach ($toRemove as $node) 
    { 
     $node->parentNode->removeChild($node); 
    } 

    return $dom->saveXML(); 
} 

// Load XML from file data.xml 
$xml = file_get_contents('data.xml'); 

$xml = renameTags($xml, 'modelNumber', 'number'); 
$xml = renameTags($xml, 'salePrice', 'price'); 

echo '<pre>'; print_r(htmlspecialchars($xml)); echo '</pre>'; 
+0

Dove esattamente carico il file XML originale? –

+0

Vedere la mia risposta aggiornata. – dfsq

+0

Funziona! Come scriveresti $ xml in un nuovo file? –

1

Esiste un codice di esempio che funziona nella mia domanda over here, ma non esiste un modo diretto per modificare il nome di un tag tramite DOMDocument/DOMElement, tuttavia è possibile copiare gli elementi con un nuovo tagname come mostrato.

pratica dovete:

function renameTag(DOMElement $oldTag, $newTagName) 
{ 
    $document = $oldTag->ownerDocument; 

    $newTag = $document->createElement($newTagName); 
    foreach($oldTag->attributes as $attribute) 
    { 
     $newTag->setAttribute($attribute->name, $attribute->value); 
    } 
    foreach($oldTag->childNodes as $child) 
    { 
     $newTag->appendChild($oldTag->removeChild($child)); 
    } 
    $oldTag->parentNode->replaceChild($newTag, $oldTag); 
    return $newTag; 
} 
+0

Dove legge il file XML da PHP? –

+0

@ RPM: http://nl.php.net/manual/en/domdocument.loadxml.php – Kris

8

Ci sono due problemi con Kris e dfsq codice:

  • Solo primo nodo figlio sarà copiato - risolto con copia temporanea di $ childNodes)
  • ll ottenere xmlns tag - risolto sostituendo il nodo all'inizio - quindi è collegato al documento

Una funzione rinominare corretto è:

function renameTag(DOMElement $oldTag, $newTagName) { 
    $document = $oldTag->ownerDocument; 

    $newTag = $document->createElement($newTagName); 
    $oldTag->parentNode->replaceChild($newTag, $oldTag); 

    foreach ($oldTag->attributes as $attribute) { 
     $newTag->setAttribute($attribute->name, $attribute->value); 
    } 
    foreach (iterator_to_array($oldTag->childNodes) as $child) { 
     $newTag->appendChild($oldTag->removeChild($child)); 
    } 
    return $newTag; 
} 
Problemi correlati