Ошибка при объединении двух документов XML с использованием XPath & DOMDocument - PullRequest
1 голос
/ 06 января 2010

Около года назад я написал библиотеку, вдохновленную jQuery, которая позволяла вам манипулировать DOM, используя PHP XPath и DOMDocument. Недавно я хотел очистить его и опубликовать как проект с открытым исходным кодом. Последние несколько дней я потратил на усовершенствования и реализацию некоторых дополнительных функций OO для PHP.

В любом случае, я подумал, что добавлю новый метод, который позволит вам объединить отдельный XML-документ с текущим. Подвох в том, что этот метод запрашивает 2 выражения XPath. Первый выбирает элементы, которые вы хотите объединить в существующий документ. Второй указывает путь назначения этих объединенных элементов.

Этот метод хорошо работает при извлечении совпадающих элементов из обоих путей, но у меня возникают проблемы с импортом сторонних элементов в текущий DOM. Я продолжаю получать страшное сообщение «Неправильная ошибка документа».

Я думал, что знаю, что делаю, но, полагаю, я был неправ. Если вы посмотрите на следующий код, вы увидите, что я сначала перебираю соответствующие элементы текущего документа, а затем соответствующие элементы внешнего документа.

Во втором вложенном цикле я пытаюсь объединить каждый внешний элемент в целевой путь в текущем документе.

Не уверен, что я делаю здесь неправильно, поскольку я явно импортирую сторонний узел в текущий документ перед его добавлением.

public function merge($source, $path_origin, $path_destination)
{
    $Dom = new self;

    if(false == $Dom->loadXml($source))
    {
        throw new DOMException('XML source could not be loaded into the DOM.');
    }

    $XPath = new DOMXPath($Dom);

    foreach($this->path($path_destination, true) as $Destination)
    {
        if(false == in_array($Destination->nodeName, array('#text', '#document')))
        {
            foreach($XPath->query($path_origin) as $Origin)
            {
                if(false == in_array($Destination->nodeName, array('#text', '#document')))
                {
                    $this->importNode($Origin, true);

                    $Destination->appendChild($Origin->cloneNode(true));
                }
            }
        }
    }

    return $this;
}

Вы можете найти библиотеку полностью в следующем репозитории Github:

http://github.com/wilhelm-murdoch/DomQuery

Halps !!!

1 Ответ

2 голосов
/ 06 января 2010

importNode не «меняет» узел, поэтому он принадлежит другому документу. Он создает новый узел, принадлежащий новому документу, и возвращает его. Таким образом, вы должны получить его возвращаемое значение и использовать , что в appendChild.

$Destination->appendChild($this->importNode($Origin, true));
...