Я использую реализацию PHP built-in DOM для изменения XML-документа, в частности файла content.xml
в электронной таблице ODS. В этом документе широко используется пространство имен (в корневом элементе объявлено 35 различных пространств имен).Как сохранить DOMNode :: cloneNode() от вставки избыточных пространств имен?
Я пытаюсь скопировать table-cell
элемент в новую строку, используя мелкий cloneNode(), но результат не совсем идентичен оригиналу:
<?xml version="1.0" encoding="UTF-8"?>
<office:document-content
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
[... snip 32 ...]>
<!-- original -->
<table:table-cell table:style-name="ce5"
office:value-type="string"
calcext:value-type="string">
<!-- cloned -->
<table:table-cell xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
table:style-name="ce5"
office:value-type="string"
calcext:value-type="string">
Хотя это семантический похоже, это может привести к серьезному раздуванию в больших таблицах (хотя XML застегнут на диске).
Есть ли решение для этого?
Наивный подход с использованием не-пространство имен, знающие метод, а просто скопировать атрибуты (включая префикс и имя тега), по-видимому, работает, на первом:
$clone = $doc->createElement($ele->tagName);
foreach ($ele->attributes as $att) {
$clone->setAttribute($att->nodeName, $att->value);
}
Результирующего XML выглядит точно так, как предполагалось. Но когда клонированный элемент манипулируют снова:
$clone->setAttributeNS($officeNS, "office:value-type", "string");
результат имеет два названия идентичны атрибутов:
<table:table-cell xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
table:style-name="ce5"
office:value-type="string"
calcext:value-type="string"
office:value-type="string"
office:string-value="">
, что делает документ недействительным. В общем, я счел невыполнимым смешивать вызовы методов с именами и именами без имени.