LINUX.ORG.RU

[PHP][DOM]: Как наложить одно XML дерево на другое?

 ,


0

0

Здравствуйте!

Раздумываю щас над такой задачкой. Есть два 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 деревьев друг на друга? Я не нашел, но может я ищу не в той области?


> Но я не пойму, как это сделать?

Никак.

К.О.

З.Ы. Надо было головой думать, когда схему делал. У тебя все теги «field», и нет способа отличить один от другого.

LamerOk ★★★★★
()

>pic_resize

В то время, как космические корабли бороздят большой театр, а в именах можно использовать "-«…

Делай руками, не?

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.