Errore Cannot read property 'childNodes' of undefined per mancanza nodo nel file xml

  • Creatore Discussione Creatore Discussione gapet
  • Data di inizio Data di inizio

gapet

Nuovo Utente
2 Ott 2018
4
0
1
Ho la necessità di creare una pagina html a partire da un file xml con javascript. Il problema che ho un errore "Cannot read property 'childNodes' of undefined" perch nel file xml manca un nodo come riporto di seguito

Codice:
<?xml version="1.0" encoding="UTF-8"?>
<Products>
 <Product>
  <InternalID>42</InternalID>
  <Code>0042</Code>
  <ImageFileName>01.png</ImageFileName>
 </Product>
 <Product>
  <InternalID>43</InternalID>
  <Code>0043</Code>
 </Product>
<Products>

Manca infatti nel secondo prodotto la riga <ImageFileName></ImageFileName>. Dato che il file è prodotto da un altro programma e quindi lo posso solo utilizzare e non modificare, cone faccio a gestire l'errore e far si che comunque renderizzo in html la pagina senza considerare quei prodotti che non hanno il riferimento <ImageFileName></ImageFileName>.

Se modifico a mano il file e poi lancio il codice Javascipt la pagina viene visualizzata con i dati e quindi l'errore viene proprio per la mancanza del nodo per alcuni prodotti, ma come ho riportato il file lo ricevo in una cartella sul sito da un altro programma
 
penso che tu possa verificare l'esistenza del nodo, in php faccio così (visto che non hai postato lo script js),
PHP:
foreach($xml->children() as $Product)
{
    echo $Product->InternalID . "<br />";

    if (isset($Product->ImageFileName)) echo $Product->ImageFileName . "<br />";
    else                                echo "l'immagine non esiste<br />";
}

con questo risultato
upload_2018-10-2_12-37-9.png
 
Grazie per la risposta, il mio problema è questo: come faccio comunque a far visualizzare la pagina anche per quei prodotti per cui il nodo non esiste? AL momento basta che uno solo dei nodi non sia presente e la pagina rimane del tutto vuota

Questo il codice che utilizzo per creare la pagina html
Codice:
<div id="demo" style='text-align:center'></div>

<script>
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "2018/w3c/articoli.xml", true);
xhttp.send();




function get_node_value (n) {    return n.childNodes[0] ? n.childNodes[0].nodeValue : "";}

function myFunction(xml) {
    var x, y, z, t, i, txt, xmlDoc;
    xmlDoc = xml.responseXML;
    txt = "";
    txt += "<div class='row'><div class='col-lg-4'>";
        x = xmlDoc.getElementsByTagName("InternalID");
    y = xmlDoc.getElementsByTagName("Code");
    z = xmlDoc.getElementsByTagName("Description");
    t = xmlDoc.getElementsByTagName("ImageFileName");
      
    
    
    var j = 0;
    for (i = 0; i < x.length; i++) {
    
        //.replace(/\s/g,'')
                
                txt += x[i].childNodes[0].nodeValue + "<br />";
                
                txt += "<img src='/2018/w3c/";
                                txt += t[i].childNodes[0].nodeValue.replace(/\s/g,'') + "'><br />";
                txt += y[i].childNodes[0].nodeValue + "<br />";
                txt += z[i].childNodes[0].nodeValue + "<br /></div>";
                
                j = j + 1
        
        
    if (j > 2) {
                  txt += "</div><div class='row'><div class='col-lg-4'>";
                  j = 0
               }             

    else {
            txt += "<div class='col-lg-4'>";
         }

    
        
    }
    
    document.getElementById("demo").innerHTML = txt;
}
</script>
 
Ho risolto così:

Codice:
<div id="demo" style='text-align:center'></div>

<script>
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "2018/w3c/articoli.xml", true);
xhttp.send();




function get_node_value (n) {    return n.childNodes[0] ? n.childNodes[0].nodeValue : "";}

function myFunction(xml) {
    var x, y, z, t, i, txt, xmlDoc;
    xmlDoc = xml.responseXML;
    txt = "";
    txt += "<div class='row'><div class='col-lg-4'>";
        x = xmlDoc.getElementsByTagName("InternalID");
    y = xmlDoc.getElementsByTagName("Code");
    z = xmlDoc.getElementsByTagName("Description");
    t = xmlDoc.getElementsByTagName("ImageFileName");
      
    
    
    var j = 0;
    for (i = 0; i < x.length; i++) {
    
        //.replace(/\s/g,'')
                
                
                
                txt += x[i].childNodes[0].nodeValue + "<br />";
                if (t[i] === undefined) {
                        "<br />";
                } else {
               txt += "<img src='/2018/w3c/";
                                txt += t[i].childNodes[0].nodeValue.replace(/\s/g,'') + "'><br />";
                }
                
                txt += y[i].childNodes[0].nodeValue + "<br />";
                txt += z[i].childNodes[0].nodeValue + "<br /></div>";
                
                j = j + 1
        
        
    if (j > 2) {
                  txt += "</div><div class='row' style='margin-top:20px'><div class='col-lg-12'>*******************************************************</div></div><div class='row'><div class='col-lg-4'>";
                  j = 0
               }             

    else {
            txt += "<div class='col-lg-4'>";
         }

    
        
    }
    
    document.getElementById("demo").innerHTML = txt;
}
</script>


Con questo controllo

Codice:
if (t[i] === undefined) {
                        "<br />";
                } else {
               txt += "<img src='/2018/w3c/";
                                txt += t[i].childNodes[0].nodeValue.replace(/\s/g,'') + "'><br />";
                }
 
Bastava usare underscore per templating e gestire il file xml come obj in javascript, sicuramente avresti scritto meno!
Codice:
_.each(data,function(valoriOBJ,key){
<div id="container<%=key%>">
<!-- html per immagine, prodotto e codice senza errori -->

<!-- o in alternativa cicli sui valori obj -->
    _.each(valoriOBJ,function(valore,key_valore){
         <div><%=key_valore%> - <%=valore%></div>
    })


</div>
})
 
Grazie Macus_adi per la risposta. Ora ho anche un aòltro problema:
Nel ciclo "var xhttp;" ho gestito una variabile l per aggiungere una class per avere sotto i dati un blocco per il pagin. Ora questo blocco ha il seguente codice
Codice:
$('#pagination-demo').twbsPagination({
totalPages: l,
In chrome il valore l valorrizato al valore della variable che si incrementata con la raccolta dei dati e la creazione delle righe del codice precedente, mentre in internet explorer e edge la variable l mi viene restituita come "undefined" e quindi il paging non riesce ad avere il valore giusto per le pagine da considerare.
 

Discussioni simili