Konumunu koruyarak bir düğüm yerine DOMXPath kullanma

2 Cevap php

Tamam, bu yüzden domBelgesi için bir yardımcı sınıf oluşturmak için, diğer gece bu temiz küçük bir fikrim yoktu o taklit, bir ölçüde, bir HTML veya XML tabanlı dize DOM işlemek için jQuery yeteneği. Yerine css seçiciler, XPath kullanılır. Örneğin:

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

Bu, her çıkan düğüm üzerinde bir geri çağırma işlevi çağırmak olacaktır. Ne yazık ki, PHP version < 5.3.x lambda işlevleri veya kapanışları desteklemiyor, bu yüzden şu an için biraz daha böyle bir şey yapmak zorunda kalıyorum:

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

Her şey şu anda harika çalışıyor ve ben bu proje bir sürü insan için yararlı olacağını düşünüyorum, ama ben işlevlerinden biri ile şaşırıp. JQuery bulunuyor 'yerine' yöntemi taklit çalışılıyor. Aşağıdaki kodu kullanarak, aşağıdaki yöntemi uygulayarak kolayca gerçekleştirebilirsiniz:

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

Bu yöntem arkasındaki kodu:

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

	return $this;
}

Şimdi, bu işleri. Bu $ İçerik klonlanmış bir versiyonu ile elde edilen her eleman yerine geçer. Sorun bu çocukların ebeveyn düğümün listesinin altına ekler olmasıdır. Soru hala DOM orijinal konumunu koruyarak nasıl, diğer öğeleri değiştirmek için bu öğe clone mi, nedir?

Ben değiştirmek oldu ters mühendislik düğüm düşünüyordum. Temel olarak, değerlerin üzerinde kopyalama, nitelikleri ve eleman ismi $ İçeriği, ama hedef elemanın gerçek eleman adını değiştirmek mümkün duyuyorum.

Yansıma bir olasılık olabilir, ama bunu yapmak için daha kolay bir yolu olmalı orada.

Kimse yok mu?

2 Cevap

ReplaceChild yerine appendChild / removeChild kullanın.

Arama $ eleman öncesinde böylece sonraki kardeş, aksi takdirde sadece append dair bir InsertBefore yaparsam çıkarmadan bir nextsibbling varsa.

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;
}

Tamamen denenmemiş olsa.

AnthonyWJones önerilen veya replaceChild, büyük oomph nasıl ben o anı kaçırdım :)