Повторяющиеся объявления пространств имен xml php DomDocument

Я использую PHP DomDocument для создания xml. Иногда пространства имен объявляются только в корневом элементе, что является предполагаемым поведением, но иногда нет. Например:

$xml = new DOMDocument("1.0",$charset);
$ns = "http://ns.com";
$otherNs = "http://otherns.com";
$docs = $xml->createElementNS($ns,"ns:Documents");
$doc = $xml->createElementNS($otherNs, "ons:Document");
$innerElement = $xml->createElementNS($otherNs, "ons:innerElement", "someValue");
$doc->appendChild($innerElement);
$docs->appendChild($doc);
$xml->appendChild($docs);
$xml->formatOutput = true;
$xml->save("dom");

Я ожидаю:

<?xml version = "1.0" encoding = "UTF-8"?>
<ns:Documents xmlns:ns = "http://ns.com" xmlns:ons = "http://otherns.com">
  <ons:Document>
    <ons:innerElement>someValue</ons:innerElement>
  </ons:Document>
</ns:Documents>

Но получил:

<?xml version = "1.0" encoding = "UTF-8"?>
<ns:Documents xmlns:ns = "http://ns.com" xmlns:ons = "http://otherns.com">
  <ons:Document xmlns:ons = "http://otherns.com">
    <ons:innerElement>someValue</ons:innerElement>
  </ons:Document>
</ns:Documents>

Почему объявление xmlns: ons = "http://otherns.com" появляется в элементе Документ, а не в innerElement? А как предотвратить дублирование?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
289
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это очень легко. Просто добавьте свои узлы в дерево документа. Кроме того, вы можете явно создать атрибут xmlns: XXX в корневом узле. См. Пример:

namespace test;

use DOMDocument;

$xml = new DOMDocument("1.0", "UTF-8");

$ns = "http://ns.com";
$otherNs = "http://otherns.com";

$docs = $xml->createElementNS($ns, "ns:Documents");
$xml->appendChild($docs);

$docs->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ons', $otherNs);

$doc = $xml->createElement("ons:Document");
$docs->appendChild($doc);

$innerElement = $xml->createElement("ons:innerElement", "someValue");
$doc->appendChild($innerElement);


$xml->formatOutput = true;

echo $xml->saveXML();

Результат:

<?xml version = "1.0" encoding = "UTF-8"?>
<ns:Documents xmlns:ns = "http://ns.com" xmlns:ons = "http://otherns.com">
  <ons:Document>
    <ons:innerElement>someValue</ons:innerElement>
  </ons:Document>
</ns:Documents>

Также обратите внимание, что DOMDocument достаточно умен, поэтому вам не нужно вызывать createElementNS (), если у вас уже объявлено пространство имен. В моем примере я просто использую createElement () с полным именем элемента.

Igor Mukhachev 20.10.2018 14:21

Вы ошибаетесь - он сериализуется только в одну и ту же строку XML. Но узел элемента создается вне пространства имен. Перед сохранением в XML выведите его $namespaceURI.

ThW 20.10.2018 22:44

Другие вопросы по теме