简体   繁体   中英

how to add xml element tag to correct place?

I have code which add item like below to xml file:

<newWord>
  <Heb>rer</Heb>
  <Eng>twew</Eng>
</newWord>

the problem is when I add element it will be not in the right place, it is out from xml tag like below.

<?xml version="1.0" encoding="UTF-8"?>
<xml>
  <newWord>
    <Heb>hebword</Heb>
    <Eng>banna</Eng>
  </newWord>
</xml>
<newWord>
  <Heb>rer</Heb>
  <Eng>twew</Eng>
</newWord>

How can I add the new element to correct place? thx

my code:

<?php    

    $wordH=$_GET['varHeb'];
    $wordE=$_GET['varEng'];


    $domtree='';

        if(!$domtree)
        {   
            $domtree = new DOMDocument('1.0', 'UTF-8');
            $domtree->formatOutput = true;
            $domtree->load('Dictionary_user.xml');
        }

        $Dictionary_user = $domtree->documentElement;

    $currentitem = $domtree->createElement("newWord");
    $currentitem = $domtree->appendChild($currentitem);

    $currentitem->appendChild($domtree->createElement('Heb', $wordH));
    $currentitem->appendChild($domtree->createElement('Eng',$wordE));

    $Dictionary_user->childNodes->item(0)->parentNode->insertBefore($currentitem,$Dictionary_user->childNodes->item(0));
        header("Content-type: text/xml");

    $domtree->save("Dictionary_user.xml");
    /* get the xml printed */
    echo $domtree->saveXML();
?>

Perhaps you want something like:

<?php 
if(!empty($_GET['varHeb']) && !empty($_GET['varEng'])){
    //Dont forget utf-8 if using Hebrew letters
    header('Content-type: text/xml; charset=utf-8');
    //Load It
    $xml = simplexml_load_file('./Dictionary_user.xml');

    //Add a new node & add the children
    $node = $xml->addChild('newWord');
    $node->addChild('Heb', trim($_GET['varHeb']));
    $node->addChild('Eng', trim($_GET['varEng']));


    //DOMDocument to format code output
    $dom = new DOMDocument('1.0', 'UTF-8');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->loadXML($xml->asXML());

    echo $dom->saveXML();
}else{
    //params not set for $_GET
}

/**
 * Result
<?xml version="1.0" encoding="UTF-8"?>
<xml>
  <newWord>
    <Heb>hebword</Heb>
    <Eng>banna</Eng>
  </newWord>
  <newWord>
    <Heb>אנחנו אוהבים גלישת מחסנית</Heb>
    <Eng>We Love Stack overflow</Eng>
  </newWord>
</xml>
*/

The issue is you doing:

$currentitem = $domtree->createElement("newWord");
$currentitem = $domtree->appendChild($currentitem);

Change it to

$currentitem = $domtree->createElement("newWord");
$currentitem = $domtree->documentElement->appendChild($currentitem);

This will them append to the root node.


There is also few other things to be improved in your code:

$wordH=$_GET['varHeb'];
$wordE=$_GET['varEng'];

Make sure you sanitize/filter this content. DOM is quite good at making sure no malicious content will be inserted, but anything coming from the outside world should be sanity checked.


$domtree='';

if(!$domtree)
{   

This is rather pointless to do. You made $domtree an empty string, so the if block will always get triggered. Remove that part and simply load the XML.


    $domtree = new DOMDocument('1.0', 'UTF-8');
    $domtree->formatOutput = true;
    $domtree->load('Dictionary_user.xml');
}

When you load a string or file with DOM, it will discard any arguments you put into the constructor and use the arguments found in the xml prolog of the string or file instead. So you do not need to supply them when newing the DOMDocument.


    $Dictionary_user = $domtree->documentElement;

This is the root node ( <xml> ) you want to append to.


$currentitem = $domtree->createElement("newWord");
$currentitem = $domtree->appendChild($currentitem);

This is where the error is happening. You create a new element and then append it to the $domtree , which is the document as a whole. In an XPath query, $domtree is / while you want to append to /xml , eg the root element.


$currentitem->appendChild($domtree->createElement('Heb', $wordH));
$currentitem->appendChild($domtree->createElement('Eng',$wordE));

This works as expected. You are adding to <newWord>


$Dictionary_user
    ->childNodes
    ->item(0)
    ->parentNode
    ->insertBefore($currentitem, $Dictionary_user->childNodes->item(0));

You are traversing from the root element ( <xml> ) to the first child element and then back up to the parent, which is the root element again obviously. So the entire traversal is not necessary. In fact, unless you want to move the appended <newWord> above the first child of the root element, the entire block is not necessary at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM