2009-08-07 10 views
16

Ho un documento XML che assomiglia a questo:Togliere spazio dei nomi da XML utilizzando PHP

<Data 
    xmlns="http://www.domain.com/schema/data" 
    xmlns:dmd="http://www.domain.com/schema/data-metadata" 
> 
    <Something>...</Something> 
</Data> 

sto parsing le informazioni utilizzando SimpleXML in PHP. Ho a che fare con gli array e sembra che abbia un problema con lo spazio dei nomi.

La mia domanda è: come rimuovere questi spazi dei nomi? Ho letto i dati da un file XML.

Grazie!

+0

Se desideri dettagli ... la mia domanda originale è stata pubblicata qui, che un utente ha già risposto (Grazie!). Ma ho scoperto che lo spazio dei nomi sta causando il mancato funzionamento dei suoi loop e restituisce un array vuoto. La domanda originale si trova qui: http://stackoverflow.com/questions/1209301/php-simplexml-group-by-element-type – jchimpo

risposta

17

Se stai usando XPath allora è una limitazione con XPath e non sguardo PHP a questa spiegazione su xpath and default namespaces per maggiori informazioni.

In particolare l'attributo xmlns="" nel nodo radice che causa il problema. Ciò significa che è necessario registrare lo spazio dei nomi, quindi utilizzare uno QName in seguito per fare riferimento agli elementi.

$feed = simplexml_load_file('http://www.sitepoint.com/recent.rdf'); 
$feed->registerXPathNamespace("a", "http://www.domain.com/schema/data"); 
$result = $feed->xpath("a:Data/a:Something/..."); 

Importante: L'URI utilizzato nella chiamata registerXPathNamespace deve essere identico a quello che viene utilizzato nel file XML vero e proprio.

+0

Giusto, quindi invece di rimuovere ... registro solo lo spazio dei nomi. E questo ha risolto il mio problema !!! Tu sei l'uomo! Grazie! – jchimpo

+0

Purtroppo, questo sembra essere l'unico modo. –

+0

Nota la sezione ** Importante **. Mi ero perso quella prima volta che ho visto questa risposta. –

1

Per rimuovere completamente lo spazio dei nomi, è necessario utilizzare le espressioni regolari (RegEx). Per esempio:

$feed = file_get_contents("http://www.sitepoint.com/recent.rdf"); 
$feed = preg_replace("/<.*(xmlns *= *[\"'].[^\"']*[\"']).[^>]*>/i", "", $feed); // This removes ALL default namespaces. 
$xml_feed = simplexml_load_string($feed); 

Allora hai spogliato qualsiasi namespace XML prima di caricare il codice XML (attenzione con la regex attraverso, perché se si dispone di tutti i campi con qualcosa di simile:

<![CDATA[ <Transfer xmlns="http://redeux.example.com">cool.</Transfer> ]]> 

Poi . metterà a nudo i xmlns dall'interno della CDATA che può portare a risultati imprevisti

+0

-1 a causa del pericolo CDATA – Alex

+0

Bello, ma non rimuove il tag di chiusura –

11

ho trovato la risposta di cui sopra per essere utile, ma non ha funzionato per me Questo ha finito per lavorare meglio:.

// Gets rid of all namespace definitions 
$xml_string = preg_replace('/xmlns[^=]*="[^"]*"/i', '', $xml_string); 

// Gets rid of all namespace references 
$xml_string = preg_replace('/[a-zA-Z]+:([a-zA-Z]+[=>])/', '$1', $xml_string); 
+3

Mi piacerebbe sbarazzarsi di "tutti i riferimenti di spazio dei nomi" con qualcosa di simile: $ xml = preg_replace ('/ (<\/*)[^>:] +:/',' $ 1 ', $ xml); –

1

Il seguente codice PHP rileva automaticamente lo spazio dei nomi predefinito specificato nel file XML sotto l'alias "predefinito". Non tutte le query XPath devono essere aggiornati per includere il prefisso default:

Quindi, se si desidera leggere file XML piuttosto che contengono una definizione di default NS o non lo fanno e si desidera interrogare tutti Something elementi, è possibile utilizzare il codice seguente:

$xml = simplexml_load_file($name); 
$namespaces = $xml->getDocNamespaces(); 
if (isset($namespaces[''])) { 
    $defaultNamespaceUrl = $namespaces['']; 
    $xml->registerXPathNamespace('default', $defaultNamespaceUrl); 
    $nsprefix = 'default:'; 
} else { 
    $nsprefix = ''; 
} 

$somethings = $xml->xpath('//'.$nsprefix.'Something'); 

echo count($somethings).' times found'; 
Problemi correlati