Jak używać jQuery do parsowania XML z przestrzeniami nazw

Jestem nowy w jQuery i chciałbym przeanalizować dokument XML.

Jestem w stanie parsować zwykły XML z domyślnymi przestrzeniami nazw, ale z XML takimi jak:

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

Wszystko czego naprawdę chcę to <z:row>.

Do tej pory używałem:

$.get(xmlPath, {}, function(xml) {
    $("rs:data", xml).find("z:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");
Bez powodzenia. Jakieś pomysły?
Author: the Tin Man, 2009-05-12

20 answers

Zajmę się tym.

Okazuje się, że wymaga \\ ucieczki okrężnicy.

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

Jak zauważył Rich:

Lepsze rozwiązanie nie wymaga ucieczki i działa na wszystkich "nowoczesnych" przeglądarkach:

.find("[nodeName=z:row]")
 135
Author: Brian Liang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-16 15:35:25

Spędziłem kilka godzin na tym czytaniu o wtyczkach i wszelkiego rodzaju rozwiązaniach bez powodzenia.

ArnisAndy opublikował link do dyskusji jQuery, gdzie ta odpowiedź jest oferowana i mogę potwierdzić, że działa to dla mnie w Chrome(v18.0), FireFox(V11.0), IE(v9.08) I Safari (V5.1.5) przy użyciu jQuery (v1.7.2).

Próbuję zeskrobać kanał WordPress, w którym treść nazywa się i to mi się udało:

content: $this.find("content\\:encoded, encoded").text()
 35
Author: Fasani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-07 20:02:36

Jeśli używasz jquery 1.5, będziesz musiał dodać cudzysłowy wokół wartości atrybutu selektora węzła, aby to działało:

.find('[nodeName="z:row"]')
 20
Author: s0laris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-12 01:16:41

Chociaż powyższa odpowiedź wydaje się być poprawna, nie działa ona w przeglądarkach webkit (Safari, Chrome). Moim zdaniem lepszym rozwiązaniem byłoby:

.find("[nodeName=z:myRow, myRow]")    
 19
Author: Rich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-01 23:50:31

W przypadku, gdy ktoś musi to zrobić BEZ jQuery , tylko z normalnym Javascript, a dla Google Chrome (webkit) , to jest jedyny sposób, który znalazłem, aby go uruchomić po wielu badaniach i testach.

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

, które będą działać przy pobieraniu następującego węzła: <prefix:name>. Jak widać prefiks lub Przestrzeń nazw jest pominięta i będzie pasować do elementów z różnymi przestrzeniami nazw pod warunkiem, że nazwa znacznika to name. Ale mam nadzieję, że to nie będzie problem dla Ciebie.

Nic z tego nie działa dla mnie (rozwijam rozszerzenie Google Chrome):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

Edytuj: po pewnym śnie, znalazłem działające obejście :) Ta funkcja zwraca pierwszy węzeł pasujący do pełnego nodeName, takiego jak <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;
}

Można go łatwo zmodyfikować w przypadku, gdy trzeba zwrócić wszystkie pasujące elementy. Mam nadzieję, że to pomoże!

 17
Author: cprcrack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-25 16:30:18

Żadne z powyższych rozwiązań nie działa tak dobrze. Znalazłem to i zostało ulepszone dla prędkości. wystarczy dodać to, działa jak urok:

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

Użycie:

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

Źródło: http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/

 14
Author: Tj Tate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-22 16:56:01

Ucieczka "\\" nie jest niezawodna i prosta

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

Metoda wydaje się być zepsuta od Jquery 1.7. Udało mi się znaleźć rozwiązanie dla 1.7, używając funkcji filtra, tutaj: Poprawa wydajności wyszukiwania węzłów Javascript XML

 9
Author: jmazella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-14 20:47:36

Warto zauważyć, że w jQuery 1.7 pojawiły się problemy z niektórymi wokół pracy znajdującymi Elementy przestrzeni nazw. Zobacz te linki, aby uzyskać więcej informacji:

 3
Author: ArnisAndy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-26 21:23:13

Znaleziono rozwiązanie w komentarzu: Parsing XML with namespaces using jQuery $().find

Użycie drugiej połowy nazwy węzła po dwukropku zadziałało. Używany .find ("lat") zamiast .find ("geo\: lat") i zadziałało.


Moja konfiguracja:

  • Chrome 42
  • jQuery 2.1.3

Przykładowy plik XML (fragment z 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>

Kod parsowania:

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
Author: Mars Robertson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:45

JQuery 1.7 nie działa z:

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

Jednym z rozwiązań, które udało mi się uruchomić w Chrome, Firefox i IE, jest użycie selektorów, które działają w IE i selektorów, które działają w Chrome, w oparciu o fakt, że jeden sposób działa w IE, a drugi w Chrome: {]}

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

W IE zwraca węzły za pomocą przestrzeni nazw (Firefox i IE wymagają przestrzeni nazw), a w Chrome selektor zwraca węzły w oparciu o selektor spoza przestrzeni nazw. Nie testowałem tego w Safari, ale powinno działać, bo działa w Chrome.

 2
Author: SeattleDiver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-26 08:27:43

Moim rozwiązaniem (ponieważ używam proxy Php) jest zastąpienie : przestrzeni nazw przez _ ... więc koniec problemów z przestrzenią nazw; -)

Keep it simple !

 2
Author: Thomas Decaux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 16:25:55

Oryginalna odpowiedź: jQuery XML parsuje jak uzyskać atrybut elementu

Oto przykład, jak pomyślnie uzyskać wartość w Chrome..

 item.description = jQuery(this).find("[nodeName=itunes\\:summary]").eq(0).text();
 2
Author: John Drefahl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:45

Od początku 2016 roku, dla mnie z jQuery 1.12.0 działa następująca składnia:

  • 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.89 m: .find("row")

Składnia .find("[nodeName=z:row]") nie działa w żadnej z wyżej wymienionych przeglądarek. Nie znalazłem sposobu na zastosowanie przestrzeni nazw w Chrome.

Łącząc to wszystko, następująca składnia działa we wszystkich przeglądarkach wymienionych powyżej: .find("row,z\\:row")

 2
Author: stefan.schwetschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 10:07:58

Jak wspomniano powyżej, istnieją problemy z powyższym rozwiązaniem z aktualnymi przeglądarkami / wersjami jQuery - sugerowana wtyczka również nie działa całkowicie z powodu problemów z wielkością liter (nodeName, jako właściwość, jest czasami we wszystkich wielkich liter). Tak więc napisałem następującą szybką funkcję:

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

Przykładowe użycie:

$.findNS($(xml), 'x:row');
 1
Author: Mike Oliver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-29 01:12:58

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

To idealne rozwiązanie...
 1
Author: sachinkondana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-23 10:34:19

Jest plugin jquery-xmlns Aby jQuery działało z przestrzeniami nazw w selektorach.

 1
Author: Dima Fomin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-22 16:54:37

Nie widziałem żadnej dokumentacji dotyczącej używania JQuery do parsowania XML. JQuery zazwyczaj używa dom przeglądarki do przeglądania dokumentu HTML, nie wierzę, że czyta sam html.

Powinieneś przyjrzeć się wbudowanej obsłudze XML w samym JavaScript.

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

 0
Author: Chris Brandsma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-12 21:59:20

Zastąpiła przestrzeń nazw pustym łańcuchem znaków. Mi pasuje. Testowane rozwiązanie w przeglądarkach: Firefox, IE, Chrome

Moim zadaniem było odczytanie i przeanalizowanie pliku EXCEL za pomocą interfejsu Sharepoint EXCEL REST API. XML-response zawiera znaczniki z przestrzenią nazw " x:".

Postanowiłem zastąpić przestrzeń nazw w XML pustym ciągiem znaków. Działa w ten sposób: 1. Get the node of interest out of the XML-response 2. Konwertuj wybrany węzeł XML-Response (Document) na ciąg znaków 2. Zamień przestrzeń nazw przez pusty łańcuch 3. Konwertuj ciąg znaków z powrotem do dokumentu XML

Zobacz zarys kodu tutaj -- >

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
}

Dla konwersji XML-to-String znajdź rozwiązanie tutaj: http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string

 0
Author: Karl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-09 18:46:27

Alternatywnie możesz użyć fast-XML-parser w swoim projekcie i przekonwertować dane XML na obiekt JS/JSON. Następnie możesz użyć go jako właściwości obiektu. Nie używa JQuery ani innych bibliotek, ale rozwiąże twój cel.

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>

Możesz ignorować przestrzenie nazw podczas parsowania do obiektu js / json. W tym przypadku możesz uzyskać bezpośredni dostęp jako jsObj.xml.data.row.

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

Disclaimer: stworzyłem fast-xml-parser.

 0
Author: Amit Kumar Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 04:19:24

W przypadku przeglądarek Webkit można po prostu pominąć dwukropek. Aby znaleźć <media:content> w kanale RSS na przykład, możesz to zrobić:

$(this).find("content");
 -1
Author: donnapep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-18 14:02:16