2010-07-29 12 views
7

XML'im var:PHP SimpleXML: belirli pozisyonda düğüm ekle

<root> 
    <nodeA /> 
    <nodeA /> 
    <nodeA /> 
    <nodeC /> 
    <nodeC /> 
    <nodeC /> 
</root> 

As ve Cs arasında "nodeB" yi nasıl ekleyebilirim? PHP'de, tercihen SimpleXML ile mi? Gibi:

<root> 
    <nodeA /> 
    <nodeA /> 
    <nodeA /> 
    <nodeB /> 
    <nodeC /> 
    <nodeC /> 
    <nodeC /> 
</root> 
+1

Yapabileceğinden emin değilim. Dokümantasyondan, SimpleXML'in ** gerçekten ** basit manipülasyon anlamına geldiği anlaşılıyor. – MvanGeest

+0

Cs'yi başka bir yerde saklayamıyorum, kaldıramaz, B ekleyebilir ve Cs'yi bu geçici konumdan geri ekleyemez miyim? PHP'de çok iyi bilemiyorum .... –

cevap

13

aşağıdaki diğer bazı SimpleXMLElement sonra yeni SimpleXMLElement eklemek için bir işlevdir. Bu, SimpleXML ile doğrudan mümkün olmadığından, işi tamamlamak için bazı DOM sınıf/yöntemlerini kullanır.

function simplexml_insert_after(SimpleXMLElement $insert, SimpleXMLElement $target) 
{ 
    $target_dom = dom_import_simplexml($target); 
    $insert_dom = $target_dom->ownerDocument->importNode(dom_import_simplexml($insert), true); 
    if ($target_dom->nextSibling) { 
     return $target_dom->parentNode->insertBefore($insert_dom, $target_dom->nextSibling); 
    } else { 
     return $target_dom->parentNode->appendChild($insert_dom); 
    } 
} 

Ve (sorunuzun özgü) nasıl kullanılabileceğine bir örnek:

$sxe = new SimpleXMLElement('<root><nodeA/><nodeA/><nodeA/><nodeC/><nodeC/><nodeC/></root>'); 
// New element to be inserted 
$insert = new SimpleXMLElement("<nodeB/>"); 
// Get the last nodeA element 
$target = current($sxe->xpath('//nodeA[last()]')); 
// Insert the new element after the last nodeA 
simplexml_insert_after($insert, $target); 
// Peek at the new XML 
echo $sxe->asXML(); 

(kod oldukça basit İsterseniz/Bunun nasıl çalıştığınıbir açıklamaya ihtiyaç olduğunu ancak yabancı kavramları içerebilir), sadece sor.

+0

Bu bana mı, yoksa simplexml_insert_after'daki $ sxe parametresi hiç kullanılmamış mı? – GolezTrol

+1

Bu siz değil mi, soruları cevaplarken neden eğlenmiyorsunuz? :) – salathe

+0

Evet, neden olmasın. :) Cevabınız için teşekkürler, b.t.w. Kendimi kurmak için kullanmak için özgürlük aldım. :) – GolezTrol

4

Salathe'nin cevabı bana yardımcı oldu, ancak SimpleXMLElement'in addChild yöntemini kullandığım için, çocukları ilk çocuk olarak daha şeffaf hale getirmek için bir çözüm aradım. çözümü DOM tabanlı işlevselliği alıp SimpleXMLElement bir alt sınıfta gizlemek için:

$xml = simplexml_load_file($inputFile, 'SimpleXMLElementEx'); 

Şimdi insertChildFirst arayabilirsiniz: Sonuçta

class SimpleXMLElementEx extends SimpleXMLElement 
{ 
    public function insertChildFirst($name, $value, $namespace) 
    { 
     // Convert ourselves to DOM. 
     $targetDom = dom_import_simplexml($this); 
     // Check for children 
     $hasChildren = $targetDom->hasChildNodes(); 

     // Create the new childnode. 
     $newNode = $this->addChild($name, $value, $namespace); 

     // Put in the first position. 
     if ($hasChildren) 
     { 
      $newNodeDom = $targetDom->ownerDocument->importNode(dom_import_simplexml($newNode), true); 
      $targetDom->insertBefore($newNodeDom, $targetDom->firstChild); 
     } 

     // Return the new node. 
     return $newNode; 
    } 
} 

, SimpleXML kullanılacak eleman sınıfı belirlemenizi sağlar yeni çocuğu ilk çocuk olarak eklemek için herhangi bir öğenin üzerinde. Yöntem, yeni elemanı bir SimpleXML öğesi olarak döndürür, bu nedenle addChild'e benzerdir. Tabii ki, öğeyi daha önce eklemek için kesin bir öğe belirtmek için bir insertChild yöntemi oluşturmak kolay olurdu, ancak şu anda ona ihtiyacım yok çünkü, ben karar verdim.

İlgili konular