باستخدام DOMXPath ليحل محل العقدة مع الحفاظ على موقفها

StackOverflow https://stackoverflow.com/questions/640815

  •  22-07-2019
  •  | 
  •  

سؤال

وطيب، حتى خطرت لي هذه الفكرة صغيرة نظيفة ليلة أخرى لإنشاء فئة المساعد لDOMDOCUMENT أن يقلد، إلى حد ما، والقدرة مسج على التلاعب في DOM من HTML أو سلسلة المستندة إلى XML. بدلا من محددات المغلق، ويستخدم كسباث. على سبيل المثال:

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

وهذا من شأنه استدعاء دالة رد على كل عقدة الناتجة عن ذلك. لسوء الحظ، PHP نسخة <5.3.x لا يدعم وظائف لامدا أو الإغلاق، لذلك أنا أجبرت على فعل شيء أكثر قليلا من هذا القبيل في الوقت الحاضر:

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

وكل شيء يعمل كبير في الوقت الحالي وأعتقد أن هذا المشروع سيكون مفيدا لكثير من الناس، ولكن أنا عالقة مع واحدة من المهام. أنا محاولة لتقليد مسج على طريقة 'استبدال'. باستخدام التعليمات البرمجية التالية، لا أستطيع تحقيق ذلك بسهولة تامة من خلال تطبيق الطريقة التالية:

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

والرمز وراء هذا الأسلوب هو:

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

    return $this;
}

والآن، وهذا يعمل. وهي تحل محل كل عنصر الناتج مع نسخة مستنسخة من $ المحتوى. المشكلة هي أنه يضيفها إلى الجزء السفلي من قائمة عقدة الأم للأطفال. والسؤال هو، كيف يمكنني استنساخ هذا العنصر لتحل محل عناصر أخرى، في حين لا يزال الإبقاء على الوضع الأصلي في DOM؟

وأنا أفكر في عقدة كنت لتحل محل الهندسة العكسية. في الأساس، ونسخ على القيم والصفات واسم عنصر من $ المحتوى، ولكن أنا غير قادر على تغيير اسم العنصر الفعلي للعنصر الهدف.

ويمكن أن يكون انعكاس هذا الاحتمال، ولكن هناك يجب ان يكون أسهل طريقة للقيام بذلك.

وأي شخص؟

هل كانت مفيدة؟

المحلول

استخدم replaceChild بدلا من appendChild / removeChild.

نصائح أخرى

وإذا بحث $ عنصر لديه nextsibbling قبل إزالة إذا كان الأمر كذلك قيام insertBefore أن الأخوة المقبل على خلاف ذلك ببساطة إلحاق.

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

ولم تختبر تماما بالرغم من ذلك.

وأو كما اقترح AnthonyWJones replaceChild أو كبيرة على الجاذبية كيف لم أفتقد تلك اللحظة:)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top