Синтаксический анализ jQuery XML с использованием пространств имен. - PullRequest
80 голосов
/ 12 мая 2009

Я новичок в jQuery и хотел бы проанализировать XML-документ.

Я могу анализировать обычный XML с пространствами имен по умолчанию, но с xml, например:

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

Все, чего я действительно хочу, это <z:row>.

Пока я занимаюсь:

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

Действительно без удачи. Есть идеи? Спасибо.

Ответы [ 20 ]

131 голосов
/ 13 мая 2009

Я понял.

Оказывается, для выхода из двоеточия требуется \\.

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

Как отметил Рич:

Лучшее решение не требует экранирования и работает во всех «современных» браузерах:

.find("[nodeName=z:row]")
35 голосов
/ 08 мая 2012

Я потратил несколько часов на чтение о плагинах и всевозможных решениях, но безуспешно.

ArnisAndy опубликовал ссылку на обсуждение jQuery, где предлагается этот ответ, и я могу подтвердить, что это работает для меня в Chrome (v18.0), FireFox (v11.0), IE (v9.08) и Safari ( v5.1.5) с использованием jQuery (v1.7.2).

Я пытаюсь очистить фид WordPress, где контент называется , и вот что сработало для меня:

content: $this.find("content\\:encoded, encoded").text()
20 голосов
/ 12 марта 2011

Если вы используете jquery 1.5, вам нужно добавить кавычки вокруг значения атрибута селектора узла, чтобы он работал:

.find('[nodeName="z:row"]')
19 голосов
/ 14 декабря 2009

Хотя приведенный выше ответ кажется правильным, он не работает в браузерах webkit (Safari, Chrome). Я считаю, что лучшим решением будет:

.find("[nodeName=z:myRow, myRow]")    
15 голосов
/ 25 июля 2011

Если кому-то нужно сделать это без jQuery , просто с обычным Javascript и для Google Chrome (webkit) , я нашел единственный способ заставить его работать после долгих исследований и испытаний.

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

Это будет работать для получения следующего узла: <prefix:name>. Как видите, префикс или пространство имен опущено, и оно будет сопоставлять элементы с различными пространствами имен при условии, что имя тега равно name. Но, надеюсь, это не станет для вас проблемой.

Ничего из этого не помогло мне (я разрабатываю расширение Google Chrome):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

Редактировать : после некоторого сна Я нашел рабочий обходной путь :) Эта функция возвращает первый узел, соответствующий полному nodeName, например <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;
}

Его можно легко изменить, если вам нужно вернуть все соответствующие элементы. Надеюсь, это поможет!

14 голосов
/ 22 июля 2013

Ни одно из приведенных выше решений не работает так хорошо. Я нашел это и был улучшен для скорости. просто добавьте это, работает как шарм:

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

использование:

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

источник: http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/

9 голосов
/ 15 декабря 2011

"\\" выход не является надежным и простым

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

Похоже, что метод не работает с Jquery 1.7. Мне удалось найти решение для 1.7, используя функцию фильтра, здесь: Улучшение производительности XML-узла Javascript

3 голосов
/ 05 мая 2015

Найденное решение в комментарии: Синтаксический анализ XML с пространствами имен с использованием jQuery $ (). Find

Использование второй половины имени узла после двоеточия работало для меня. Использовал .find ("lat") вместо .find ("geo \: lat") , и это сработало для меня.


Моя настройка:

  • Chrome 42
  • jQuery 2.1.3

Пример XML (фрагмент из API контактов Google):

<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@example.com" primary="true"/>
</entry>

Код разбора:

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

Плнкр: http://plnkr.co/edit/l8VzyDq1NHtn5qC9zTjf?p=preview

3 голосов
/ 27 марта 2012

Стоит отметить, что в jQuery 1.7 возникали проблемы с некоторыми обходными путями поиска элементов пространства имен. Смотрите эти ссылки для получения дополнительной информации:

2 голосов
/ 14 марта 2013

Оригинальный ответ: Синтаксический анализ jQuery XML, как получить атрибут элемента

Вот пример того, как успешно получить значение в Chrome.

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