wake-up-neo.com

jQuery XML-Analyse mit Namespaces

Ich bin neu bei jQuery und würde gerne ein XML-Dokument analysieren.

Ich kann normales XML mit den Standard-Namespaces analysieren, jedoch mit XML wie:

<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>

Alles was ich wirklich will ist der <z:row>.

Bisher habe ich gemacht:

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

Mit wirklich keinem Glück. Irgendwelche Ideen? Vielen Dank.

79
Brian Liang

Ich habe es verstanden.

Es stellt sich heraus, dass \\ erforderlich ist, um den Doppelpunkt zu verlassen.

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

Wie Rich darauf hinwies:

Die bessere Lösung erfordert keine Flucht und funktioniert auf allen "modernen" Browsern:

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

Ich habe mehrere Stunden damit verbracht, über Plugins und alle möglichen Lösungen ohne Erfolg zu lesen.

ArnisAndy hat einen Link zu einer jQuery-Diskussion gepostet, in der diese Antwort angeboten wird, und ich kann bestätigen, dass dies in Chrome (Version 18.0), FireFox (Version 11.0), IE (Version 9.08) und Safari (Version 5.1.5) funktioniert ) mit jQuery (v1.7.2).

Ich versuche, einen WordPress-Feed zu kratzen, in dem der Inhalt <content: encoded> heißt und das hat bei mir funktioniert:

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

Wenn Sie Jquery 1.5 verwenden, müssen Sie den Attributwert des Knotenselektors in Anführungszeichen setzen, damit er funktioniert:

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

Die obige Antwort scheint zwar richtig zu sein, funktioniert jedoch nicht in Webkit-Browsern (Safari, Chrome). Eine bessere Lösung wäre meiner Meinung nach:

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

Falls jemand dies tun muss ohne jQuery, nur mit normalem Javascript, und für Google Chrome (Webkit), ist dies der einzige Weg, den ich gefunden habe um es nach vielen Recherchen und Tests zum Laufen zu bringen.

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

Das funktioniert zum Abrufen des folgenden Knotens: <prefix:name>. Wie Sie sehen, wird das Präfix oder der Namespace weggelassen und es werden Elemente mit unterschiedlichen Namespaces abgeglichen, vorausgesetzt, der Tag-Name lautet name. Aber hoffentlich ist das kein Problem für Sie.

Nichts davon hat bei mir funktioniert (Ich entwickle eine Google Chrome -Erweiterung):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

Bearbeiten: Nach etwas Schlaf Ich habe eine Abhilfe gefunden :) Diese Funktion gibt die erste zurück Knoten, der einem vollständigen nodeName entspricht, z. B. <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;
}

Es kann leicht geändert werden, falls Sie alle übereinstimmenden Elemente zurückgeben müssen. Ich hoffe es hilft!

15
cprcrack

Keine der oben genannten Lösungen funktioniert so gut. Ich fand das und wurde für die Geschwindigkeit verbessert. fügen Sie einfach dieses hinzu, das wie ein Zauber gearbeitet hat: 

$.fn.filterNode = function(name) {
    return this.find('*').filter(function() {
       return this.nodeName === name;
    });
};

verwendungszweck: 

var ineedthatelementwiththepsuedo = $('someparentelement').filterNode('dc:creator');

source: http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/

14
Tj Tate

Die "\\" - Flucht ist nicht narrensicher und einfach 

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

Die Methode scheint seit Jquery 1.7 gebrochen zu sein. Ich konnte unter Verwendung einer Filterfunktion eine Lösung für 1.7 finden. Hier: Verbesserung der Javascript-XML-Knotensuche

9
jmazella

Es ist erwähnenswert, dass ab jQuery 1.7 Probleme mit einigen der Problemumgehungen für das Auffinden von Elementen mit Namensbereich aufgetreten sind. Siehe diese Links für weitere Informationen:

3
ArnisAndy

Lösung im Kommentar gefunden: Analyse von XML mit Namespaces mithilfe von jQuery $ (). Find

Die zweite Hälfte des Knotennamens nach dem Doppelpunkt funktionierte für mich. Verwendete .find ("lat") anstelle von .find ("geo \: lat") und es hat für mich funktioniert.


Mein Setup:

  • Chrome 42
  • jQuery 2.1.3

Beispiel-XML (Ausschnitt aus der Google Contacts API):

<entry>
  <id>http://www.google.com/m8/feeds/contacts/mstefanow%40gmail.com/base/0</id>
  <Gd:email rel="http://schemas.google.com/g/2005#other" address="[email protected]" primary="true"/>
</entry>

Code analysieren:

var xmlDoc = $.parseXML( xml );
var $xml = $( xmlDoc );
var $emailNode = $xml.find( "email" );
$("#email").html($emailNode.attr("address"));

Plnkr: http://plnkr.co/edit/l8VzyDq1NHtn5qC9zTjf?p=preview

3
Michal Stefanow

jQuery 1.7 funktioniert nicht mit folgendem: 

$(xml).find("[nodeName=a:IndexField2]")

Eine Lösung, die ich in Chrome, Firefox und IE verwenden konnte, besteht darin, Selektoren zu verwenden, die in IE UND - Selektoren funktionieren, die in Chrome funktionieren, basierend auf der Tatsache, dass eine Möglichkeit funktioniert in IE und der andere in Chrome:

$(xml).find('a\\\\:IndexField2, IndexField2')

Im IE werden Knoten zurückgegeben, die den Namespace verwenden (Firefox und IE erfordern den Namespace). In Chrome gibt der Selektor Knoten basierend auf dem Selector für Nicht-Namespaces zurück. Ich habe dies nicht in Safari getestet, aber es sollte funktionieren, da es in Chrome funktioniert.

2
SeattleDiver

Ursprüngliche Antwort: jQuery XML-Analyse zum Abrufen des Elementattributs

Hier ein Beispiel, wie Sie den Wert in Chrome erfolgreich abrufen können.

 item.description = jQuery(this).find("[nodeName=iTunes\\:summary]").eq(0).text();
2
jdrefahl

Seit Anfang 2016 funktioniert für mich folgende Syntax mit jQuery 1.12.0:

  • IE 11 (11.0.9600.18204, Update 11.0.28, KB3134815): .find("z\\:row")
  • Firefox 44.0.2: .find("z\\:row")
  • Chrome 44.0.2403.89m: .find("row")

Die Syntax .find("[nodeName=z:row]") funktioniert in keinem der oben genannten Browser. Ich habe keine Möglichkeit gefunden, einen Namespace in Chrome anzuwenden.

Alles in allem funktioniert die folgende Syntax in allen oben genannten Browsern: .find("row,z\\:row")

2

Meine Lösung (weil ich einen PHP-Proxy benutze) ist: Namespace durch _ zu ersetzen ... also keine Namespace-Probleme mehr ;-)

Halte es einfach !

2
Thomas Decaux

Es gibt ein Plugin jquery-xmlns für jQuery, um mit Namensräumen in Selektoren zu arbeiten.

1
Dima Fomin

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

ist die perfekte Lösung ...

1
MackMon

Wie oben erwähnt, gibt es bei der obigen Lösung Probleme mit aktuellen Browsern/Versionen von jQuery. Das vorgeschlagene Plug-In funktioniert auch aufgrund von Fallproblemen nicht vollständig (nodeName als Eigenschaft ist manchmal in Großbuchstaben). Also habe ich die folgende Schnellfunktion geschrieben:

$.findNS = function (o, nodeName)
{
    return o.children().filter(function ()
    {
        if (this.nodeName)
            return this.nodeName.toUpperCase() == nodeName.toUpperCase();
        else
            return false;
    });
};

Verwendungsbeispiel:

$.findNS($(xml), 'x:row');
1
Mike Oliver

Ich habe keine Dokumentation zur Verwendung von JQuery zum Analysieren von XML gesehen JQuery verwendet normalerweise den Browser dom, um ein HTML-Dokument zu durchsuchen. Ich glaube nicht, dass es die HTML-Datei selbst liest.

Sie sollten sich wahrscheinlich die integrierte XML-Behandlung in JavaScript selbst ansehen.

http://www.webreference.com/programming/javascript/definitive2/

0
Chris Brandsma

der Namespace wurde einfach durch eine leere Zeichenfolge ersetzt. Funktioniert gut für mich. Getestete Lösung für alle Browser: Firefox, IE, Chrome

Meine Aufgabe bestand darin, eine Excel-Datei über die Sharepoint Excel REST - API zu lesen und zu analysieren. Die XML-Antwort enthält Tags mit dem Namensraum "x:".

Ich entschied mich dafür, den Namespace in der XML durch eine leere Zeichenfolge zu ersetzen. Funktioniert auf diese Weise: 1. Holen Sie den interessierenden Knoten aus der XML-Antwort 2. Konvertieren Sie den ausgewählten Knoten XML-Response (Document) in String 2. Ersetzen Sie den Namespace durch eine leere Zeichenfolge 3. Konvertieren Sie den String zurück in das XML-Dokument

Siehe Code-Gliederung hier ->

function processXMLResponse)(xData)
{
  var xml = TOOLS.convertXMLToString("", "",$(xData).find("entry content")[0]);
  xml = xml.replace(/x:/g, "");            // replace all occurences of namespace
  xData =  TOOLS.createXMLDocument(xml);   // convert string back to XML
}

Für die Konvertierung von XML in String finden Sie hier eine Lösung: http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string

0
Karl

Alternativ können Sie fast-xml-parser in Ihrem Projekt verwenden und die XML-Daten in ein JS/JSON-Objekt konvertieren. Dann können Sie es als Objekteigenschaft verwenden. Es verwendet nicht JQuery oder andere Bibliotheken, aber es löst Ihren Zweck.

var xmlData = '<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>'

var jsObj = parser.parse(xmlData,{attrPrefix:"",ignoreTextNodeAttr: false});
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][0],null,4) + "<br>");
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][1],null,4) + "<br>");
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][2],null,4) + "<br>");
<script src="https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/2.9.2/parser.min.js"></script>

Sie können Namespaces ignorieren, während Sie das Objekt js/json analysieren. In diesem Fall können Sie direkt auf jsObj.xml.data.row zugreifen.

for(var i=0; i< jsObj.xml.data.row.length; i++){
  console.log(jsObj.xml.data.row[i]);
}

Disclaimer: Ich habe fast-xml-Parser erstellt.

0