Pergunta

Ok, então eu tive esta pequena idéia pura na outra noite para criar uma classe auxiliar para DomDocument que imita, em certa medida, a capacidade do jQuery para manipular o DOM de um HTML ou string baseada em XML. Em vez de seletores css, XPath é usado. Por exemplo:

$Xml->load($source)
    ->path('//root/items')
    ->each(function($Context)
    {
        echo $Context->nodeValue;
    });

Este seria chamar uma função de chamada de retorno em cada nó resultante. Infelizmente, a versão do PHP <5.3.x faz funções lambda não apoio ou encerramento, então eu sou forçado a fazer algo um pouco mais parecido com isso por enquanto:

$Xml->load($source)
    ->path('//root/items')
    ->walk('printValue', 'param1', 'param2');

Tudo está funcionando muito bem no momento e acho que esse projeto seria útil para muita gente, mas eu estou preso com uma das funções. Eu estou tentando método 'substituir' imitador do jQuery. Usando o seguinte código, eu posso fazer isso muito facilmente, aplicando o método a seguir:

$Xml->load($source)
    ->path('//root/items')
    ->replace($Xml->createElement('foo', 'bar')); // can be an object, string or XPath pattern

O código por trás deste método é:

public function replace($Content)
{
    foreach($this->results as $Element)
    {
        $Element->parentNode->appendChild($Content->cloneNode(true));
        $Element->parentNode->removeChild($Element);
    }

    return $this;
}

Agora, isso funciona. Ele substitui cada elemento resultante com uma versão clonada de US $ conteúdo. O problema é que ele adiciona-los para o fundo da lista do nó pai das crianças. A questão é: como faço para clonar este elemento para substituir outros elementos, mantendo a posição original no DOM?

Eu estava pensando sobre engenharia reversa do nó eu era substituir. Basicamente, copiando sobre os valores, atributos e nome do elemento de US $ conteúdo, mas eu sou incapaz de mudar o nome do elemento real do elemento alvo.

Reflexão poderia ser uma possibilidade, mas tem de haver uma maneira mais fácil de fazer isso.

Anybody?

Foi útil?

Solução

Use replaceChild vez de appendChild / removeChild.

Outras dicas

Lookup se $ elemento tem um nextsibbling antes de remover se assim for fazer uma insertBefore que próximo irmão de outra forma simplesmente acréscimo.

public function replace($Content)
{
        foreach($this->results as $Element)
        {
                if ($Element->nextSibling) {
                    $NextSiblingReference = $Element->nextSibling;
                    $Element->parentNode->insertBefore($Content->cloneNode(true),$NextSiblingReference);
                }
                else {
                    $Element->parentNode->appendChild($Content->cloneNode(true));   
                }
                $Element->parentNode->removeChild($Element);
        }

        return $this;
}

embora totalmente testado.

Ou, como AnthonyWJones sugeriu replaceChild , grande oomph como eu perder aquele momento:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top