0

I use the following code to write values to an xml file in php.

if(isset($_POST['title']) && isset($_POST['content'])){
    $news = new DOMDocument();
    $news->load('../files/news.xml');

    $parentNode = $news->getElementById('newsContainer');
    $newsNodes  = $news->getElementsByTagName('News');

    echo $_POST['content'];

    if($newsNodes->length > 0){
        $newsItem = $news->createElement('News');

        $newsItemTitle = $news->createElement('Title');
        $newsItemTitle->nodeValue = $_POST['title'];

        $newsItemContent = $news->createElement('Content');
        $newsItemContent->nodeValue = $_POST['content']; //The value I assign here gets cut out

        $newsItem->appendChild($newsItemTitle);
        $newsItem->appendChild($newsItemContent);
        $news->documentElement->appendChild($newsItem);

        $result = $news->save('../files/news.xml');

        if($result == FALSE){
            echo 'false';
        }else{
            echo 'true';
        }
    }else{
        $newNewsContentNode = new DOMDocument();

        $newsContainer = $newNewsContentNode->createElement('NewsContainer');
        $newsItem = $newNewsContentNode->createElement('News');

        $newsItemTitle = $newNewsContentNode->createElement('Title');
        $newsItemTitle->nodeValue = $_POST['title'];

        $newsItemContent = $newNewsContentNode->createElement('Content');
        $newsItemContent->nodeValue = $_POST['content']; //The value I assign here gets cut out

        $newsItem->appendChild($newsItemTitle);
        $newsItem->appendChild($newsItemContent);
        $newsContainer->appendChild($newsItem);

        $newNewsContentNode->appendChild($newsContainer);

        $result = $newNewsContentNode->save('../files/news.xml');

        if($result == FALSE){
            echo 'false';
        }else{
            echo 'true';
        }

    }

}

I save a string with 1065 characters in it but when I check the xml file the node contains only a part of the given string. I looked at the string which comes through the POST and it comes fine. What am I doing wrong here?

Imesh Chandrasiri
  • 5,558
  • 15
  • 60
  • 103
  • Please reduce your example code to demonstrate the issue to the point. That should also prevent you from posting unrelated code. And it should help to clear things up quick. / and just a note fyi: createElement in PHP allows you to pass the element value directly: https://secure.php.net/manual/en/domdocument.createelement.php – hakre Jul 11 '15 at 20:34
  • If you see strings in node-values cut or dropped, this can be a character encoding issue. That normally become only visible at output. You have to provide valid UTF-8 strings, just assigning `$_POST` fields shows, that you're not checking for that. Related: [Regex to detect Invalid UTF-8 String](http://stackoverflow.com/q/11709410/367456) – hakre Jul 11 '15 at 20:37

1 Answers1

1

Do not use the DOMNode::$nodeValue or the second argument to DOMDocument::createElement() with variable values. Here is an escaping bug that can break the resulting XML.

$dom = new DOMDocument();
$dom->appendChild($dom->createElement("foo"));
$dom->documentElement->nodeValue = 'a & b';
echo $dom->saveXml();

Output:

Warning: main(): unterminated entity reference b in /tmp/execpad-145b170ab9f7/source-145b170ab9f7 on line 5
<?xml version="1.0"?>
<foo>a </foo>

You need to use DOMDocument::createTextNode() to avoid the problem.

$dom = new DOMDocument();
$dom->appendChild($dom->createElement("foo"));
$dom->documentElement->appendChild(
  $dom->createTextNode('a & b')
);
echo $dom->saveXml();

Output:

<?xml version="1.0"?>
<foo>a &amp; b</foo>
ThW
  • 19,120
  • 3
  • 22
  • 44