في SimpleXML، كيف يمكنني إضافة بسيطة موجودة كعنصر طفل؟

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

  •  12-09-2019
  •  | 
  •  

سؤال

لدي كائن بسيط كائن $ الطفل، وجوه بسيطة كائن $ الأصل.

كيف يمكنني إضافة طفل دولار كطفل من والد دولار؟ هل هناك أي طريقة للقيام بذلك دون تحويل إلى دوم والظهر؟

يبدو أن الأسلوب AddChild () قد تسمح لي فقط بإنشاء عنصر جديد وفريغ، ولكن هذا لا يساعد عندما يكون العنصر الذي أرغب في إضافة طفل $ به أيضا أطفال. أنا أفكر أنني قد أحتاج إلى الإصابة هنا.

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

المحلول

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

إذا كان SimpleXML يعالجك بلطف في جميع الأماكن الأخرى، فأنت تريد التمسك بها، لا يزال لديك خيار القفز إلى وظائف DOM مؤقتا لأداء ما تحتاج إليه، ثم القفز مرة أخرى، باستخدام dom_import_simplexml() و simplexml_import_dom(). وبعد لست متأكدا مدى كفاءة هذا، ولكن قد يساعدك.

نصائح أخرى

لسوء الحظ SimpleXMLElement لا يقدم أي شيء لجلب عنصرين معا. كما كتب nickf., ، إنه أكثر تركيبا للقراءة أكثر من التلاعب. ومع ذلك، فإن الامتداد الشقيقة DOMDocument هو التحرير ويمكنك إحضارها معا dom_import_simplexml(). وبعد و يظهر salathe في إجابة ذات صلة كيف يعمل هذا للحصول على بسيطة محددة.

ويبين ما يلي كيف يعمل هذا مع فحص الإدخال وبعض الخيارات. أفعل ذلك مع اثنين من الأمثلة. المثال الأول هو وظيفة لإدراج سلسلة XML:

/**
 * Insert XML into a SimpleXMLElement
 *
 * @param SimpleXMLElement $parent
 * @param string $xml
 * @param bool $before
 * @return bool XML string added
 */
function simplexml_import_xml(SimpleXMLElement $parent, $xml, $before = false)
{
    $xml = (string)$xml;

    // check if there is something to add
    if ($nodata = !strlen($xml) or $parent[0] == NULL) {
        return $nodata;
    }

    // add the XML
    $node     = dom_import_simplexml($parent);
    $fragment = $node->ownerDocument->createDocumentFragment();
    $fragment->appendXML($xml);

    if ($before) {
        return (bool)$node->parentNode->insertBefore($fragment, $node);
    }

    return (bool)$node->appendChild($fragment);
}

تتيح هذه الوظيفة المثالية إلحاق XML أو إدراجها قبل عنصر معين، بما في ذلك عنصر الجذر. بعد معرفة ما إذا كان هناك شيء لإضافته، فإنه يستخدم Domdocument. وظائف وطرق إدراج XML كجزء مستند، كما هو موضح في كيفية استيراد سلسلة XML في Domdocument PHP. وبعد مثال الاستخدام:

$parent = new SimpleXMLElement('<parent/>');

// insert some XML
simplexml_import_xml($parent, "\n  <test><this>now</this></test>\n");

// insert some XML before a certain element, here the first <test> element
// that was just added
simplexml_import_xml($parent->test, "<!-- leave a comment -->\n  ", $before = true);

// you can place comments above the root element
simplexml_import_xml($parent, "<!-- this works, too -->", $before = true);

// but take care, you can produce invalid XML, too:
// simplexml_add_xml($parent, "<warn><but>take care!</but> you can produce invalid XML, too</warn>", $before = true);

echo $parent->asXML();

هذا يعطي الناتج التالي:

<?xml version="1.0"?>
<!-- this works, too -->
<parent>
  <!-- leave a comment -->
  <test><this>now</this></test>
</parent>

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

/**
 * Insert SimpleXMLElement into SimpleXMLElement
 *
 * @param SimpleXMLElement $parent
 * @param SimpleXMLElement $child
 * @param bool $before
 * @return bool SimpleXMLElement added
 */
function simplexml_import_simplexml(SimpleXMLElement $parent, SimpleXMLElement $child, $before = false)
{
    // check if there is something to add
    if ($child[0] == NULL) {
        return true;
    }

    // if it is a list of SimpleXMLElements default to the first one
    $child = $child[0];

    // insert attribute
    if ($child->xpath('.') != array($child)) {
        $parent[$child->getName()] = (string)$child;
        return true;
    }

    $xml = $child->asXML();

    // remove the XML declaration on document elements
    if ($child->xpath('/*') == array($child)) {
        $pos = strpos($xml, "\n");
        $xml = substr($xml, $pos + 1);
    }

    return simplexml_import_xml($parent, $xml, $before);
}

تقوم هذه الوظيفة المثالية بتطبيع قائمة العناصر والسمات مثل الشائع في SimpleXML. قد ترغب في تغييره لإدراج عدة كلمات مرور متعددة مرة واحدة، ولكن كما يظهر مثال الاستخدام أدناه، لا يدعم المثال الخاص بي (انظر مثال السمات):

// append the element itself to itself
simplexml_import_simplexml($parent, $parent);

// insert <this> before the first child element (<test>)
simplexml_import_simplexml($parent->children(), $parent->test->this, true);

// add an attribute to the document element
$test = new SimpleXMLElement('<test attribute="value" />');
simplexml_import_simplexml($parent, $test->attributes());

echo $parent->asXML();

هذا هو استمرار من مثال الاستخدام الأول. لذلك الناتج الآن هو:

<?xml version="1.0"?>
<!-- this works, too -->
<parent attribute="value">
  <!-- leave a comment -->
  <this>now</this><test><this>now</this></test>
<!-- this works, too -->
<parent>
  <!-- leave a comment -->
  <test><this>now</this></test>
</parent>
</parent>

آمل أن يكون هذا مفيدا. يمكنك ابحث عن الرمز في GIST و كما التجريبي عبر الإنترنت / نظرة عامة على الإصدار PHP..

في الواقع، من الممكن (ديناميكيا) إذا كنت تنظر بعناية addChild() ويعرف. لقد استخدمت هذه التقنية لتحويل أي مجموعة إلى XML باستخدام Recursion ومرجع المرور

  • addChild() عائدات SimpleXMLElement من الطفل المضافة.
  • لإضافة عقدة ورقة، واستخدام $xml->addChilde($nodeName, $nodeValue).
  • لإضافة عقدة قد يكون لها مباندا أو قيمة، استخدم$xml->addChilde($nodeName), ، لا يتم تمرير قيمة إلى addChild(). وبعد هذا سيؤدي إلى وجود فرعي من النوع SimpleXMLEMement! ليس سلسلة!

الهدف XML

<root>
    <node>xyz</node>
    <node>
        <node>aaa</node>
        <node>bbb</node>
    </node>
</root>

رمز:

$root = new SimpleXMLElement('<root />');
//add child with name and string value.
$root.addChild('node', 'xyz'); 
//adds child with name as root of new SimpleXMLElement
$sub = $root->addChild('node');
$sub.addChild('node', 'aaa');
$sub.addChild('node', 'bbb');

ترك هذا هنا كما تعثرت على هذه الصفحة ووجدت أن SimpleXML يدعم الآن هذه الوظيفة من خلال :: طريقة Addchild..

يمكنك استخدام هذه الطريقة لإضافة أي عناصر متتالية أيضا:

$xml->addChild('parent');
$xml->parent->addChild('child');
$xml->parent->child->addChild('child_id','12345');
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top