Undefined when reading XML file in JS

1

On an HTML5 page with JS that I have to do, I have to simulate RSS with an XML file (which simulates an html with a couple of own tags), which has articles, first showing a header with a link to the description . At the moment, the file reads it and shows well, except for a detail that unbalances me, jumps an undefined for each line that shows, in addition to the content.

JS:

    function loadDoc() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function()
    {
        if (this.readyState == 4 && this.status == 200)
            myFunction(this);    

    };

    xhttp.open("GET", "data/articles.xml", true);
    xhttp.send();
}

function mostrar(x,texto)
{
    var listado;
    listado+="<div onclick='unhide("+texto+")'> ";
    listado+="<p>";

    listado+=x.getElementsByTagName("h2")[0].childNodes[0].nodeValue; 
    listado+="</p>\n";
    listado+="</div>\n<hr />\n<br /> \n";

    return listado;
}

function myFunction(xml) {
    var i;

    var listado="";

    var x = xml.responseXML.getElementsByTagName("articulo"); 

    for (i = 0; i <x.length; i++)
    { 

        listado+=mostrar(x[i],'a'+i) //Si no llamo a una función externa, sobreescribe lo que ya había


    }

    document.getElementById("ninguno").innerHTML = listado;
}

XML:

<articulos>
    <articulo>
        <article>
            <h2>TEST</h2>
            <p></p>
        </article>
        <img href=''></img>
    </articulo>
    <articulo>
        <article>
            <h2>prueba</h2>
            <p></p>
        </article>
        <img href=''></img>
    </articulo>

</articulos>

Result:

The css I doubt it is necessary, but here goes:

div {
    border-radius: 25px;
    padding: 20px; 
    width: 200px;
    height: 150px;    

}

#hidden
{
    display:none;
}
    
asked by myenemy 23.03.2017 в 16:55
source

2 answers

0

Even if you have found the solution, I think it's good for you to know that you can do the same and easier by DOMParser . This function has a function (in the prototype, worth the redundancy) called parseFromString that receives two parameters:

  • Text representation of a certain format
  • Mother to convert.

It will return a document . From this, you can select nodes like any DOM selection.

Example

let xml = '
<articulos>
    <articulo>
        <article>
            <h2>Introducción a ES6</h2>
            <p></p>
        </article>
        <img href='https://abc.com/axy'></img>
    </articulo>
    <articulo>
        <article>
            <h2>Primeros pasos con MongoDB</h2>
            <p></p>
        </article>
        <img href='https://xyz.com/plq'></img>
    </articulo>
</articulos>
'.trim();

let xmlDoc = new DOMParser().parseFromString(xml, 'text/xml');
let articles = xmlDoc.getElementsByTagName('articulo');
let articlesData = [].map.call(articles, function(article) {
  let content = article.querySelector('article');
  let link = article.querySelector('img');

  return {
    title: content.querySelector('h2').textContent,
    href: link.getAttribute('href')
  };
});

let list = document.getElementById('articles');

articlesData.forEach(function(data) {
  let li = document.createElement('li');
  let a = document.createElement('a');
  li.appendChild(a);

  a.href = data.href;
  a.textContent = data.title;

  list.appendChild(li);
});
body {
  background-color: #fff;
  padding: 50px;
}

@import url('https://fonts.googleapis.com/css?family=Noto+Sans:400,700');
h4 {
  color: #777;
  display: inline-block;
  font-family: 'Noto Sans';
  margin: 0;
}

ul {
  color: #555;
  list-style: inside;
  padding: 0;
}

a {
  color: #555;
  font-family: 'Noto Sans';
  font-size: 15px;
  display: inline-block;
  padding: 8px 10px;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

.box {
  border-radius: 5px;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .23), 0 -1px 1px 0 rgba(0, 0, 0, .1);
}

.box-header {
  background-color: #f9f9f9;
  border-bottom: 1px solid #eee;
  padding: 15px;
}

.box-body {
  padding: 15px 20px;
}
<div class="box">
  <header class="box-header">
    <h4>Artículos</h4>
  </header>
  <article class="box-body">
    <ul id="articles"></ul>
  </article>
</div>
    
answered by 23.03.2017 в 20:07
0

I have found the problem ... That I am stupid or something. That undefined that appears is because it tries to put "null", which is the reason why I start the listing in my_function to an empty string.

You just have to initialize it also in show, staying:

function mostrar(x,texto)
{
    var listado="";
    listado+="<div onclick='unhide("+texto+")'> ";
    listado+="<p>";

    listado+=x.getElementsByTagName("h2")[0].childNodes[0].nodeValue; 
    listado+="</p>\n";
    listado+="</div>\n<hr />\n<br /> \n";

    return listado;
}
    
answered by 23.03.2017 в 19:51