2009-08-07 15 views
16

Mam dokumentu XML, który wygląda tak:Usuń nazw z XML za pomocą PHP

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

ja analizowania informacji przy użyciu SimpleXML w PHP. Mam do czynienia z tablicami i wydaje mi się, że mam problem z przestrzenią nazw.

Moje pytanie brzmi: Jak usunąć te przestrzenie nazw? Czytam dane z pliku XML.

Dziękujemy!

+0

Jeśli chcesz poznać szczegóły ... moje oryginalne pytanie zostało zamieszczone tutaj, a użytkownik już odpowiedział (dzięki!). Ale dowiedziałem się, że przestrzeń nazw powoduje, że jego pętle nie działają i zwracają pustą tablicę. Oryginalne pytanie znajduje się tutaj: http://stackoverflow.com/questions/1209301/php-simplexml-group-by-element-type – jchimpo

Odpowiedz

17

Jeśli używasz XPath to jest to ograniczenie z XPath i nie PHP spojrzenie na to wyjaśnienie xpath and default namespaces aby uzyskać więcej informacji.

Dokładniej jego atrybut xmlns="" w głównym węźle, który powoduje problem. Oznacza to, że musisz zarejestrować przestrzeń nazw, a następnie użyć QName, aby odnieść się do elementów.

$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/..."); 

Ważne: URI stosowane w zaproszeniu registerXPathNamespace musi być identyczny z tym, który jest używany w rzeczywistym pliku XML.

+0

Dobrze, więc zamiast usuwać ... Po prostu rejestruję przestrzeń nazw. I to naprawiło mój problem !!! Jesteś mężczyzną! Dzięki! – jchimpo

+0

Niestety, wydaje się, że to jedyny sposób. –

+0

Zwróć uwagę na sekcję ** Ważne **. Tęskniłem za tym, kiedy po raz pierwszy zobaczyłem tę odpowiedź. –

1

Aby całkowicie usunąć przestrzeń nazw, należy użyć Wyrażeń regularnych (RegEx). Na przykład:

$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); 

Potem już pozbawiony jakichkolwiek nazw xml przed załadowaniem XML (należy uważać za pośrednictwem regex, ponieważ jeśli masz jakieś pól z czymś takim:

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

Wtedy to . obetnie xmlns od wewnątrz CDATA, co może prowadzić do nieoczekiwanych wyników

+0

-1 ze względu na niebezpieczeństwo CDATA – Alex

+0

Ładnie, ale nie usuwa znacznika zamykającego –

11

znalazłem odpowiedź powyżej, aby być pomocny, ale nie bardzo działa na mnie to skończyło się lepiej pracuje.

// 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

Pozbyłbym się "odniesień do wszystkich przestrzeni nazw" z czymś takim: $ xml = preg_replace ('/ (<\/*)[^>:] +:/',' $ 1 ', $ xml); –

1

Poniższy kod PHP automatycznie wykrywa domyślną przestrzeń nazw podaną w pliku XML pod aliasem "default". Żadne zapytania Xpath nie muszą być aktualizowane tak, aby zawierały przedrostek default:

Jeśli chcesz odczytywać pliki XML, a zawierają domyślną definicję NS, a nie chcesz i chcesz wysłać zapytanie do wszystkich elementów Something, możesz użyć następujący kod:

$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'; 
Powiązane problemy