87 votes

Analyse XML jQuery avec des espaces de noms

Je suis nouveau sur jQuery et voudrais analyser un document XML.

Je suis en mesure d'analyser le code XML standard avec les espaces de noms par défaut, mais avec XML comme:

 <xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
   <s:Schema id="RowsetSchema">
     <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
       <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1">
        <s:datatype dt:type="i4" dt:maxLength="4" />
      </s:AttributeType>
       <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
       <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
       <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
    </s:ElementType>
  </s:Schema>
   <rs:data>
    <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" />
    <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" />
    <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" />
  </rs:data>
</xml>
 

Tout ce que je veux vraiment, ce sont les <z:row> .

Jusqu'ici, j'ai fait:

 $.get(xmlPath, {}, function(xml) {
    $("rs:data", xml).find("z:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");
 

Avec vraiment pas de chance. Des idées? Merci.

139voto

Brian Liang Points 4375

J? ai compris.

Il s'avère qu'il faut \\ pour échapper au côlon.

 $.get(xmlPath, {}, function(xml) {
    $("rs\\:data", xml).find("z\\:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");
 

Comme l'a souligné Rich:

La meilleure solution ne nécessite pas de fuite et fonctionne sur tous les navigateurs "modernes":

 .find("[nodeName=z:row]")
 

35voto

Fasani Points 311

J'ai passé plusieurs heures à lire des informations sur les plug-ins et toutes sortes de solutions sans succès.

ArnisAndy a posté un lien vers une discussion jQuery, où cette réponse est proposée et je peux confirmer que cela fonctionne pour moi dans Chrome (v18.0), FireFox (v11.0), IE (v9.08) et Safari (v5.1.5 ) en utilisant jQuery (v1.7.2).

J'essaie de gratter un flux WordPress dont le contenu est nommé <content: encoded> et voici ce qui a fonctionné pour moi:

 content: $this.find("content\\:encoded, encoded").text()
 

19voto

Rich Points 366

Bien que la réponse ci-dessus semble être correcte, elle ne fonctionne pas dans les navigateurs Webkit (Safari, Chrome). Une meilleure solution serait, selon moi:

 .find("[nodeName=z:myRow, myRow]")    
 

19voto

s0laris Points 381

Si vous utilisez jquery 1.5, vous devrez ajouter des guillemets autour de la valeur de l'attribut sélecteur de nœud pour que cela fonctionne:

 .find('[nodeName="z:row"]')
 

17voto

cprcrack Points 3040

Dans le cas où quelqu'un doit le faire sans jQuery, juste avec Javascript normale, et pour Google Chrome (webkit), c'est le seul moyen que j'ai trouvé pour le faire fonctionner après beaucoup de recherches et de tests.

parentNode.getElementsByTagNameNS("*", "name");

Qui va travailler pour récupérer le nœud suivant: <prefix:name>. Comme vous pouvez le voir le préfixe ou un espace de noms est omis, et il va faire correspondre les éléments avec différents espaces de noms fourni le nom de la balise est - name. Mais j'espère que ce ne sera pas un problème pour vous.

Rien de tout cela a fonctionné pour moi (je développe un Google Chrome extension):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

Edit: après quelques heures de sommeil, j'ai trouvé un travail solution de contournement :) Cette fonction renvoie le premier nœud correspondant à un plein nodeName comme <prefix:name>:

// Helper function for nodes names that include a prefix and a colon, such as "<yt:rating>"
function getElementByNodeName(parentNode, nodeName)
{   
    var colonIndex = nodeName.indexOf(":");
    var tag = nodeName.substr(colonIndex + 1);
    var nodes = parentNode.getElementsByTagNameNS("*", tag);
    for (var i = 0; i < nodes.length; i++)
    {
        if (nodes[i].nodeName == nodeName) return nodes[i]
    }
    return undefined;
}

Il peut facilement être modifié dans le cas où vous devez retourner tous les éléments correspondants. Espérons que cela aide!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X