Pergunta

Eu tenho um documento XML que se parece com o seguinte:

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

Estou analisando as informações usando o simpexml no PHP. Estou lidando com matrizes e pareço estar tendo um problema com o espaço para nome.

Minha pergunta é: como faço para remover esses namespaces? Eu li os dados de um arquivo XML.

Obrigada!

Foi útil?

Solução

Se você está usando o XPath, é uma limitação com XPath e não PHP Veja esta explicação em XPath e namespaces padrão para mais informações.

Mais especificamente é o xmlns="" atributo no nó raiz que está causando o problema. Isso significa que você precisará registrar o espaço de nome e usar um Qname depois de se referir a elementos.

$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: O URI usado no registerXPathNamespace A chamada deve ser idêntica à usada no arquivo XML real.

Outras dicas

Eu achei a resposta acima útil, mas não funcionou muito para mim. Isso acabou funcionando melhor:

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

O código PHP a seguir detecta automaticamente o espaço de nome padrão especificado no arquivo XML sob o alias "padrão". Nenhuma todas as consultas XPath devem ser atualizadas para incluir o prefixo default:

Então, se você quiser ler arquivos XML, em vez disso, eles contêm uma definição de NS padrão ou não e você quer consultar tudo Something Elementos, você pode usar o seguinte código:

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

Para remover completamente o espaço para nome, você precisará usar expressões regulares (regex). Por exemplo:

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

Em seguida, você retirou algum espaço para xml antes de carregar o XML (tenha cuidado com o Regex, porque se você tiver algum campo com algo como:

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

Em seguida, ele retirará os XMLNs de dentro dos CDATA, o que pode levar a resultados inesperados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top