2009-12-10 9 views
2

Je ne peux pas comprendre comment accéder aux données entre les balises imbriquées internes. Quand je lance ce javascript, tout ce que je vois est "Null".xml parsing dom

Voici ce que mon fichier xml nommé "bboard.xml" ressemble à:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!-- Designed by Someone --> 
<bulletinboard> 
<article> 
<title lang="en"><h2>eeeeeeeeegg #1</h2></title> 
<detail><span class="detail">aaaaapple</span>&lt;a href="../data/csr.html#artcl1"> ...more &lt;/a></detail> 
<date>12/09/09</date> 
</article> 
</bulletinboard> 

Voici le javascript nommé "loadxmldoc.js":

function loadXMLDoc(dname) 
{ 
try //Internet Explorer 
    { 
    xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); 
    } 
catch(e) 
    { 
    try //Firefox, Mozilla, Opera, etc. 
    { 
    xmlDoc=document.implementation.createDocument("","",null); 
    } 
    catch(e) {alert(e.message)} 
    } 
try 
    { 
    xmlDoc.async=false; 
    xmlDoc.load(dname); 
    return(xmlDoc); 
    } 
catch(e) {alert(e.message)} 
return(null); 
} 

Et enfin, voici la page HTML réelle où je veux afficher le résultat de javascript. Il est appelé « javdemo.html »:

<html> 
<head> 
<script type="text/javascript" src="loadxmldoc.js"> 
</script> 
</head> 

<body> 


<div> 
<script type="text/javascript"> 
xmlDoc=loadXMLDoc("bboard.xml"); 

var x=xmlDoc.getElementsByTagName("title"); 
var y=xmlDoc.getElementsByTagName("detail"); 
var z=xmlDoc.getElementsByTagName("date"); 

document.write("<h4>"+"A Live Bulletin Board"+"</h4>"); 
     for (i=0;i<x.length;i++) 
    { 

    document.write("<h1>"+x[i].childNodes[0].nodeValue+"</h1>"); 
    document.write(y[i].childNodes[0].nodeValue); 
    document.write(z[i].childNodes[0].nodeValue); 
    document.write("<p>"+"&nbsp;"+"</p>"); 
    // document.write("</div>") 
    } 
</script> 
</div> 
</body> 
</html> 

Ce ne sera probablement pas montrer le code complet dans votre navigateur. En passant, comment échapper les balises html ici sur le débordement de la pile?

+0

Quelle est exactement la sortie désirée?Est-ce '

eeeeeeeeegg # 1

aaaaapple12/09/09'? –

+0

Oui. La sortie doit être eeeeeeeeeegg et aaaaaple lors du rendu. – megatr0n

Répondre

2
z[i].childNodes[0].nodeValue 

... est OK. Le firstChild de z[0] est un noeud Text, dont nodeValue (ou data) est '12/09/09'.

x[i].childNodes[0].nodeValue 

... n'est pas très bon. x[0] est un noeud avec ElementtagName égal à 'h2'. Les éléments n'ont aucun nodeValue, d'où le null.

On pourrait dire x[i].firstChild.firstChild.data pour obtenir les données à partir du noeud Textintérieur l'élément <h2>, en supposant qu'il y a toujours exactement un.

En utilisant document.write pour sortir les chaînes que vous obtenez est également problématique. S'il y a des choses comme &lt;script> dans le contenu du texte et que vous écrivez cela en HTML sans échapper, vous avez une vulnérabilité de type cross-site-scripting.

Si ce que vous avez réellement besoin de faire est d'extraire le contenu de l'élément du document XML, ce n'est pas si facile. Il n'y a pas de moyen standard pour re-sérialiser le contenu du noeud à partir d'un élément XML simple comme s'il y avait le DOM HTML avec HTMLElement.innerHTML. Ce que vous pouvez faire est de recurse dans les enfants en recréant les nœuds XML Element et Text en tant que nœuds HTML. La méthode document.importNode devrait être en mesure de le faire, sauf qu'il ne fonctionne pas dans IE, de sorte que vous auriez à faire vous-même:

<div id="board"></div> 
<script type="text/javascript"> 
    var xdoc= loadXMLDoc('board.xml'); 
    var titles= xmlDoc.getElementsByTagName('title'); 
    var details= xmlDoc.getElementsByTagName('detail'); 
    var dates= xmlDoc.getElementsByTagName('date'); 

    var board= document.getElementById('board'); 
    for (var i= 0; i<titles.length; i++) { 
     appendImportedInner(board, titles[i]); 
     appendImportedInner(board, details[i]); 
     board.appendChild(appendImportedInner(document.createElement('p'), dates[i])); 
    } 

    // Import Text and Element nodes inside a parent XML node to a target HTML node 
    // Currently ignores any other type of node, such as comments 
    // 
    function appendImportedInner(dest, parent) { 
     for (var i= 0; i<parent.childNodes.length; i++) { 
      var child= parent.childNodes[i]; 
      if (child.nodeType==3) { // TEXT_NODE 
       dest.appendChild(document.createTextNode(child.data)); 
      } 
      if (child.nodeType==1) { // ELEMENT_NODE 
       dest.appendChild(document.createElement(child.tagName)); 
       for (var ai= 0; ai<child.attributes.length; ai++) { 
        var attr= child.attributes[ai]; 
        dest.lastChild.setAttribute(attr.name, attr.value); 
       } 
       appendImportedInner(dest.lastChild, child); 
      } 
     } 
     return dest; 
    } 
</script> 

le faire avec des méthodes DOM permet d'oublier méchant document.write et régler la contenu à tout moment plus tard dans le processus de chargement, ce qui signifie également que vous pouvez rendre le chargement du document XML asynchrone avec un rappel pour remplir le tableau, au lieu du chargeur synchrone que vous avez en ce moment.

Dans tous les cas, Document.load utilisé dans votre actuel loadXMLDoc() n'est pas une méthode DOM XML standard et ne fonctionnera pas sur WebKit (Chrome, Safari, ...). Pour charger un fichier XML à partir du serveur, il vaut mieux utiliser un XMLHttpRequest normal pour le récupérer: il est plus simple et plus largement compatible.

+0

J'ai essayé votre code et je reçois une page complètement vide maintenant dans IE. Même chose dans Firefox. Fondamentalement, je voulais montrer le lien hypertexte à partir de xml et je ne peux pas penser à un autre moyen de le faire, comme vous le dites en série de xml. – megatr0n

+0

Fonctionne pour moi (juste le bloc de code ci-dessus, après l'include 'loadxmldoc'). – bobince

+0

Merci. Ça fonctionne maintenant. Juste corrigé "board.xml" en "bboard.xml". – megatr0n