Смешанный XML, сгенерированный из разных источников + PHP Xpath

Я генерирую файл XML из многих источников. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я передаю новый XML из веб-службы Soap и из других файлов XML, которые создаются другим приложением. Поскольку xml из веб-службы возвращается с префиксом пространства имен, мне нужно удалить префикс из веб-службы soap или получить префикс пространства имен из веб-службы soap и добавить его в XML-файл, созданный другим приложением.

Например, из мыльного веб-сервиса:

<s:element1></s:element1>

Из другого приложения:

<element2></element2>

И мне нужно создать xml следующим образом:

<element1></element1>
<element2></element2>

или же

<s:element1></s:element1>
<s:element2></s:element2>

Я думаю, что первый подход будет проще.

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

Я использую XPath для создания нового сгенерированного файла XML.

Спасибо!

0

Решение

Нет, вам не нужно удалять или изменять префиксы пространства имен. Пространства имен важны, префиксы — нет. Они просто псевдонимы, которые упрощают чтение XML.

В следующем примере показаны 3 разных xmls, которые все анализируют на элементе с локальным именем foo в пространстве имен urn:example,

$xmls = [
'<f:foo xmlns:f="urn:example"/>',
'<bar:foo xmlns:bar="urn:example"/>',
'<foo xmlns="urn:example"/>'
];

foreach ($xmls as $xml) {
$document = new DOMDocument();
$document->loadXml($xml);
var_dump(
$document->documentElement->localName,
$document->documentElement->namespaceURI
);
}

Выход:

string(3) "foo"string(11) "urn:example"string(3) "foo"string(11) "urn:example"string(3) "foo"string(11) "urn:example"

Таким образом, информация доступна в каждом узле. Если вы импортируете узел в документ, он принесет с собой свое пространство имен, сохраняя информацию.

$xmls = [
'<f:foo xmlns:f="urn:example"/>',
'<bar:foo xmlns:bar="urn:example"/>',
'<foo xmlns="urn:example"/>'
];

$target = new DOMDocument();
$target->loadXml('<f:foo xmlns:f="urn:example"/>');

foreach ($xmls as $xml) {
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('e', 'urn:example');
$target->documentElement->appendChild(
$target->importNode($xpath->evaluate('/e:foo')->item(0), TRUE)
);
}

echo $target->saveXml(), "\n\n";

Выход:

<?xml version="1.0"?>
<f:foo xmlns:f="urn:example"><f:foo/><bar:foo xmlns:bar="urn:example"/><f:foo/></f:foo>

Для Xpath вы должны зарегистрировать свой собственный префикс для пространства имен. Это может быть тот же префикс, что и в документе, или другой. Если все сделано правильно, префикс пространства имен в документе не имеет значения:

$xpath = new DOMXpath($target);
$xpath->registerNamespace('e', 'urn:example');
var_dump($xpath->evaluate('count(//e:foo)'));

Выход:

float(4)
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]