Здравствуйте!
Раздумываю щас над такой задачкой. Есть два XML дерева - базовое и дополнительное, которое нужно «наложить» на базовое. Пример:
Базовое дерево:
<query name="first_query">
<!-- Новости -->
<table name="news">
<field name="time">
<about val="Время"/>
<size val="10"/>
</field>
<field name="title">
<about val="Заголовок"/>
<size val="250"/>
</field>
<field name="text">
<about val="Текст"/>
<size val="4096"/>
</field>
</table>
<!-- Картинки -->
<table name="picture">
<field name="time">
<about val="Время добавления файла"/>
<size val="10"/>
</field>
<field name="file">
<about val="Файл картинки"/>
<filename_size val="1000"/>
</field>
<field name="title">
<about val="Описание файла"/>
<size val="250"/>
</field>
</table>
</query>
Дополнительное дерево:
<query name="second_query">
<!-- Новости -->
<table name="news">
<field name="time">
<defaultvalue val="autotime"/>
<size val="20"/>
</field>
<field name="public">
<about val="Разрешить публикацию новости"/>
<size val="1"/>
</field>
</table>
<!-- Картинки -->
<table name="picture">
<field name="file">
<pic_resize val="320x200"/>
</field>
</table>
</query>
Дополнительное дерево должно накладываться на базовое по следующим правилам:
1. Должны добавляться узлы, которых нет в исходном дереве.
2. Значения атрибутов, переопределенных в дополнительном дереве, должны заменить собой значения атрибутов в базовом дереве.
То есть, результирующее дерево должно выглядеть так:
<query name="reult_query">
<!-- Новости -->
<table name="news">
<field name="time">
<about val="Время"/>
<size val="20"/>
<defaultvalue val="autotime"/>
</field>
<field name="title">
<about val="Заголовок"/>
<size val="250"/>
</field>
<field name="text">
<about val="Текст"/>
<size val="4096"/>
</field>
<field name="public">
<about val="Разрешить публикацию новости"/>
<size val="1"/>
</field>
</table>
<!-- Картинки -->
<table name="picture">
<field name="time">
<about val="Время добавления файла"/>
<size val="10"/>
</field>
<field name="file">
<about val="Файл картинки"/>
<filename_size val="1000"/>
<pic_resize val="320x200"/>
</field>
<field name="title">
<about val="Описание файла"/>
<size val="250"/>
</field>
</table>
</query>
Вопрос: Каким образом это сделать?
Я уже попробовал преобразовывать DOM-деревья в ассоциативные массивы вот такго формата: http://paste.org.ru/?d2qfug.
Затем объединяю массивы с помощью функции array_merge_recursive_distinct(), которую можно найти тут: http://php.net/manual/en/function.array-merge-recursive.php, а затем полученный массив обратно преобразовывать в DOM.
Но проблема в том, что, например, элементы table и элементы field обозначены числовыми индексами. И узел
<pic_resize val=«320x200»/>
вставляется в нужный элемент <table> (так как в обоих деревьях элементов <table> два), но в <field name=«time»> вместо <field name=«file»>. Заодно, у этого <field> появляются два атрибута name.
Это происходит потому, что в базовом дереве во второй таблице первым идет элемент <field name=«time»>, а в дополнительном дереве первым идет элемент <field name=«file»>. Этот первый элемент дополнительного дерева и накладывается на первый элемент базового дерева. А должен накладываться на второй. Но я не пойму, как это сделать?
Я тут уже думаю сделать какое-нибудь другое, линейное представление деревьев, чтобы решить эту задачу. Но что-то не могу придумать формат в котором легко можно будет сращивать деревья.
Кто что думает по этому вопросу? Может уже есть готовые накладывалки XML деревьев друг на друга? Я не нашел, но может я ищу не в той области?