Search code examples
javascriptphpxmlxmlhttprequest

'getElementsByTagName' of null from php generated xml


So I'm creating a little something for my work. A couple of XML files to hold news items among other databases. Why I don't use an actual database? Work policy reasons which may change.

But for now I produce the following admin.php:

<div id="news" style="display:none;">
    <div style="float:left;width:40%;">
    <h1>Regionala Nyheter</h1>
    <table border="0"><tr><td><b>Rubrik: </b></td><td><input id="rntitle" type="text" /></p></td></tr>
    <tr><td></td><td><textarea id="rntext" rows=10 cols=40></textarea></td></tr>
    <tr><td></td><td><input type="button" value="Spara" onclick="editnews(0,-2)" /></td></tr></table>
    <div id="regnews"></div>
    </div>
</div>

...

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
    var rnxhttp = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
    var RNDoc;
    var el_news;
    var el_regnews;
    var numrn = 0;

    rnxhttp.onreadystatechange = function()
    {
        if (rnxhttp.readyState == 4 && rnxhttp.status == 200)
        {
            RNDoc = rnxhttp.responseXML;
            refresh_regnews();
        }
    };

    onload = function()
    {
        el_regnews = document.getElementById("regnews");
        el_news = document.getElementById("news");
        el_news.style.display = "block";
        rnxhttp.open("GET", "regnews.xml", true);
        rnxhttp.send();
    }

    var refresh_regnews = function()
    {
        var inhtext = "";
>>      numrn = RNDoc.getElementsByTagName("entry").length;
        for(var i=0; i<numrn; i++)
        {
            var entry = RNDoc.getElementsByTagName("entry")[i];
            var edate = entry.getElementsByTagName("date")[0].childNodes[0].nodeValue;
            var etitle = entry.getElementsByTagName("title")[0].childNodes[0].nodeValue;
            var etext = entry.getElementsByTagName("text")[0].childNodes[0].nodeValue.split("\n");
            inhtext = inhtext + "<br /><br /><div style='width:90%;border-style:ridge;'>"
            inhtext = inhtext + "<table border='0'><tr><td><b>Rubrik: </b></td><td colspan='2'><input id='cntitle" + i + "' type='text' value='" + etitle + "' /></p></td></tr>";
            inhtext = inhtext + "<tr><td></td><td colspan='2'><textarea id='cntext' rows=10 cols=40>";
            for(var j=1; j<etext.length; j++)
                inhtext = inhtext + etext[j].trim() + "\n";
            inhtext = inhtext + "</textarea></td></tr><tr><td></td>"
            inhtext = inhtext + "<td><input type='button' value='Spara' onclick='editnews(0," + i + ")' /></td><td><input type='button' value='Radera' /></td></tr></table></div>";
        }
        el_regnews.innerHTML = inhtext;
    }

    var editnews = function(newstype,newsindex)
    {
        var newstitle = "";
        var newstext = "";
        if(newstype==0)
        {
            if(newsindex<0)
            {
                newstitle = document.getElementById("rntitle").value;
                newstext = document.getElementById("rntext").value;
            }
            else
            {
                newstitle = document.getElementById("rntitle" + newsindex).value;
                newstext = document.getElementById("rntext" + newsindex).value;
            }
        }
        $.ajax({
            type: "POST",
            url: "submit.php",
            data:{ add: 1, type: newstype, index: newsindex, title: newstitle, text: newstext  },
            success: function(data){
                console.log(data);
                console.log(ajax.responseText);
            }
        });
    }
</script>

>> shows where the error occurs. The error is:

Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
    at refresh_regnews (admin.php:106)
    at XMLHttpRequest.rnxhttp.onreadystatechange (admin.php:68)

There is quite a bit missing from this, but I'm giving as much of the essentials as possible. I have pre-created the regnews.xml file with header and "root-tag" so that the submit.php has something to work with (and not sure if their server will allow the creation of new files).

After a few submits, regnews.xml looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<newsitems>
    <entry>
        <date>2017/09/04 - 19:45:32</date>
        <title>Säkerheten Först</title>
        <text>
            Vi tar säkerheten på största alvar!
            &lt;img src="http://www.edwardleuf.org/gradiant.bmp" /&gt;
        </text>
    </entry>
    <entry>
        <date>2017/09/04 - 19:45:32</date>
        <title>Säkerheten I Förhand</title>
        <text>
            Vi tar säkerheten på största alvar!

        </text>
    </entry>
    <entry>
        <date>2017/09/04 - 19:45:32</date>
        <title>Kontainrarna Blockerade</title>
        <text>
            Och stacketet fick lida. &lt;i&gt;Eller kanske bilen själv?&lt;/i&gt;
        </text>
    </entry>
    <entry>
        <date>2017/09/09 - 12:55:16</date>
        <title>Vi bygger nytt<title>
        <text>
            Varje dag bygger vi något nytt.

            Man kan undra varför.
        </text>
    </entry>
    <entry>
        <date>2017/09/09 - 12:57:31</date>
        <title>Vi bygger nytt<title>
        <text>
            Varje dag bygger vi något nytt.

            Man kan undra varför.
        </text>
    </entry>
    <entry>
        <date>2017/09/09 - 12:57:46</date>
        <title>Vi bygger nytt<title>
        <text>
            Varje dag bygger vi något nytt.

            Man kan undra varför.
        </text>
    </entry>
</newsitems>

So, with all that, I have to wonder why the XMLHttpRequest() can't find the <entry> tags. Or have I spellt something wrong in the code somewhere? The funny part is that when I had just one <entry> to test with, it worked fine.

Tested in Chrome only (no LastPass) because that is most likely what work is going to use.


Solution

  • Actually the RNDoc is null because responseXML requires completely valid XML it returns null. Consider to check the responding XML, firstly it needs Content-Type in the response headers sent from the server.