SimpleXML, nasıl bir alt öğesi olarak varolan SimpleXMLElement ekleyebilirsiniz?

4 Cevap php

Ben bir SimpleXMLElement $ nesne çocuk var, ve bir SimpleXMLElement nesnesi $ ebeveyn.

Nasıl $ ebeveyn bir çocuk olarak $ çocuğu ekleyebilirsiniz? Geri DOM dönüştürme olmadan bunu yapmanın bir yolu var mı?

AddChild () yöntemi yalnızca bana yeni, boş bir öğe oluşturmak için izin gibi görünüyor, ama eleman ben $ çocuk da çocuğu var eklemek istediğiniz zaman yardımcı olmuyor. Ben burada yinelemeye gerekebilir düşünüyorum.

4 Cevap

Ben bu en yararlı cevap değil biliyorum, ama XML değiştirerek / oluştururken, özellikle beri, ben DOM işlevlerini kullanarak üzerinden geçiş istiyorum. SimpleXML en basit belgeleri erişim için iyi, ancak bunları değiştirmeden oldukça zayıf.

SimpleXML tüm diğer yerlerde lütfen sizi tedavi ve onunla sopa istiyorsanız [(0)], hala gerekenleri gerçekleştirmek için geçici DOM işlevleri üzerinde atlama seçeneği var ve sonra {kullanarak, tekrar atlamak } and simplexml_import_dom() . Bunun ne kadar etkili emin değilim, ama o size yardımcı olabilir.

Ben sadece bu sayfada tökezledi ve SimpleXML şimdi ::addChild method aracılığıyla bu işlevi destekleyen bulundu burada bu bırakmak.

Siz de herhangi bir geçişli öğeler eklemek yapmak için bu yöntemi kullanabilirsiniz:

$xml->addChild('parent');
$xml->parent->addChild('child');
$xml->parent->child->addChild('child_id','12345');

Ne yazık ki SimpleXMLElement does not offer anything to bring two elements together. As @nickf wrote, bu düzenleme için daha okuma için daha uygun. Ancak, kardeş uzatma DOMDocument düzenleme için ve bu özel SimpleXMLElement için çalışıyor dom_import_simplexml() . And @salathe shows in a related answer nasıl vasıtasıyla birbirine hem de getirebilir.

Aşağıdaki gösterir nasıl giriş kontrol ve biraz daha fazla seçenek ile bu iş. Ben iki örnek ile bunu. İlk örnek, bir XML dizesi eklemek için bir fonksiyon:

/**
 * 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);
}

Bu örnek fonksiyon XML eklemek veya kök öğesi dahil, belirli bir unsur önce eklemenizi sağlar. Eklemek için bir şey olup olmadığını öğrendikten sonra, bir belge parçası olarak XML eklemek için DOMDocument işlevleri ve yöntemleri kullanan, aynı zamanda How to import XML string in a PHP DOMDocument özetlenmiştir. Kullanım örneği:

$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();

Bu şu çıktıyı verir:

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

İkinci bir örnek, SimpleXMLElement sokulması edilir. Gerekirse bu ilk işlev kullanır. Orada hiç bir şey olduğunu ve hangi elemanın tür ithal edilecek ise temelde kontrol eder. Bir nitelik ise, sadece bir unsur ise, bu XML içine tefrika ve daha sonra XML olarak üst öğe eklenecek, katacak:

/**
 * 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);
}

Bu örnek fonksiyon elemanlarının listesini normalleştirmek yapar ve SimpleXML ortak gibi bağlıyor. Bir kerede birden fazla SimpleXMLElement eklemek için değiştirmek isteyebilirsiniz, ama kullanım örneği aşağıda gösterildiği gibi, benim örnek (nitelikler örneğe bakın) bu desteklemez:

// 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();

Bu ilk kullanım-örneğin bir devamıdır. Bu nedenle çıktı şimdi:

<?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>

Bu yararlı olduğunu umuyoruz. You can find the code in a gist gibi online demo / PHP version overview.

Eğer addChild() nasıl tanımlandığını dikkatli bakarsanız aslında, (dinamik) mümkündür. Ben özyineleme kullanarak XML herhangi bir dizi dönüştürmek ve pass-by-reference için bu tekniği kullanılır

  • Eklendi çocuğun addChild() döner SimpleXMLElement.
  • yaprak düğüm eklemek için kullanın $xml->addChilde($nodeName, $nodeValue).
  • to add a node which may have subnode or value, use $xml->addChilde($nodeName), no value is passed to addChild(). This will result in having a subnode of type SimpleXMLElement! not a string!

target XML

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

Code:

$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');