Удалить пространство имен из XML с помощью PHP - PullRequest
18 голосов
/ 07 августа 2009

У меня есть XML-документ, который выглядит следующим образом:

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

Я анализирую информацию, используя SimpleXML в PHP. Я имею дело с массивами и, похоже, у меня проблемы с пространством имен.

Мой вопрос: как мне удалить эти пространства имен? Я читаю данные из файла XML.

Спасибо!

Ответы [ 4 ]

16 голосов
/ 07 августа 2009

Если вы используете XPath, то это ограничение для XPath и , а не PHP, посмотрите на это объяснение xpath и пространства имен по умолчанию для получения дополнительной информации.

В частности, это атрибут xmlns="" в корневом узле, который вызывает проблему. Это означает, что вам нужно зарегистрировать пространство имен, а затем использовать QName для ссылки на элементы.

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

Важно : URI, используемый в вызове registerXPathNamespace, должен совпадать с тем, который используется в реальном XML-файле.

14 голосов
/ 04 октября 2011

Я нашел ответ выше, чтобы быть полезным, но он не совсем работал для меня. В итоге получилось лучше:

// 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);
1 голос
/ 30 октября 2012

Следующий код PHP автоматически определяет пространство имен по умолчанию, указанное в файле XML под псевдонимом «default». Нет необходимости обновлять все запросы xpath, чтобы включить префикс default:

Так что, если вы хотите читать XML-файлы, а не содержать определение NS по умолчанию, или же нет, и вы хотите запросить все элементы Something, вы можете использовать следующий код:

$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';
0 голосов
/ 07 августа 2009

Чтобы полностью удалить пространство имен, вам нужно использовать регулярные выражения (RegEx). Например:

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

Затем вы удалили все пространства имен xml перед загрузкой XML (будьте осторожны с регулярным выражением, потому что если у вас есть поля с чем-то вроде:

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

Затем он удалит xmlns изнутри CDATA, что может привести к неожиданным результатам.

...