Я новичок в 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");
на самом деле не повезло. Есть идеи?
javascript
jquery
xml
namespaces
xsd
Брайан Лян
источник
источник
Ответы:
Я понял.
Оказывается, это требует
\\
выхода из толстой кишки.$.get(xmlPath, {}, function(xml) { $("rs\\:data", xml).find("z\\:row").each(function(i) { alert("found zrow"); }); }, "xml");
Как заметил Рич:
Лучшее решение не требует экранирования и работает во всех «современных» браузерах:
.find("[nodeName=z:row]")
источник
$('[nodeName=rs:data]', xml).find('[nodeName=z:row]')
- работает с 1.3.2 под WebKit (где метод экранированного двоеточия явно не работает)$('[nodeName=rs:data],data')
rs
,dt
илиs
на самом деле не пространств имен. Пространства имен - это URN в верхней части файла. Префиксы - это просто псевдонимы, выбранные автором документа для краткости. Один и тот же документ с одинаковыми пространствами имен может быть создан с совершенно разными префиксами. Я рекомендую всем искать API, которые понимают пространства имен, вместо того, чтобы использовать префиксы в ваших запросах. Например, в DOM API браузера вы можете использоватьgetElementByTagNameNS()
иgetAttributeNS()
.Я безуспешно читал несколько часов о плагинах и всевозможных решениях.
ArnisAndy опубликовал ссылку на обсуждение jQuery, где предлагается этот ответ, и я могу подтвердить, что это работает для меня в Chrome (v18.0), FireFox (v11.0), IE (v9.08) и Safari (v5.1.5). ) с помощью jQuery (v1.7.2).
Я пытаюсь очистить канал WordPress, где контент называется <content: encoded>, и это то, что у меня сработало:
content: $this.find("content\\:encoded, encoded").text()
источник
.each()
цикл для перебораitem
элементов:$('dc\\:creator, creator', this).text()
. Хотя я не уверен, зачем это, creator
было нужно, иdc\\:creator
не просто работало.Если вы используете jquery 1.5, вам нужно будет добавить кавычки вокруг значения атрибута селектора узла, чтобы он работал:
.find('[nodeName="z:row"]')
источник
Хотя приведенный выше ответ кажется правильным, он не работает в браузерах webkit (Safari, Chrome). Я считаю, что лучшим решением было бы:
.find("[nodeName=z:myRow, myRow]")
источник
$('[nodeName=rs:data],data')
Если кому-то нужно это сделать без jQuery , только с обычным Javascript и для Google Chrome (webkit) , это единственный способ заставить его работать после большого количества исследований и тестирования.
Это будет работать для получения следующего узла:
<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; }
Его можно легко изменить, если вам нужно вернуть все совпадающие элементы. Надеюсь, поможет!
источник
Ни одно из приведенных выше решений не работает так хорошо. Я нашел это, и скорость была улучшена. просто добавьте это, работает как шарм:
$.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/
источник
Экранирование "\\" не является надежным, и простой
.find('[nodeName="z:row"]')
Метод, похоже, не работает с JQuery 1.7. Мне удалось найти решение для версии 1.7, используя функцию фильтра, здесь: Повышение производительности поиска узлов XML в Javascript
источник
Стоит отметить, что начиная с jQuery 1.7 были проблемы с некоторыми обходными путями для поиска элементов пространства имен. Смотрите эти ссылки для получения дополнительной информации:
источник
Нашел решение в комментарии: Разбор XML с пространствами имен с помощью jQuery $ (). Find
Моя установка:
Пример XML (фрагмент из 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@example.com" primary="true"/> </entry>
Код парсинга:
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
источник
jQuery 1.7 не работает со следующим:
$(xml).find("[nodeName=a:IndexField2]")
Одно из решений, которое я смог использовать в Chrome, Firefox и IE, - это использовать селекторы, которые работают в IE, и селекторы, которые работают в Chrome, исходя из того факта, что один способ работает в IE, а другой - в Chrome:
$(xml).find('a\\\\:IndexField2, IndexField2')
В IE это возвращает узлы с использованием пространства имен (Firefox и IE требуют пространства имен), а в Chrome селектор возвращает узлы на основе селектора без пространства имен. Я не тестировал это в Safari, но он должен работать, потому что он работает в Chrome.
источник
Мое решение (потому что я использую прокси-сервер Php) - заменить: namespace на _ ... чтобы больше не было проблем с пространством имен ;-)
Будь проще !
источник
Исходный ответ: парсинг jQuery XML, как получить атрибут элемента
Вот пример того, как успешно получить значение в Chrome ..
item.description = jQuery(this).find("[nodeName=itunes\\:summary]").eq(0).text();
источник
По состоянию на начало 2016 года для меня с jQuery 1.12.0 работает следующий синтаксис:
.find("z\\:row")
.find("z\\:row")
.find("row")
Синтаксис
.find("[nodeName=z:row]")
не работает ни в одном из упомянутых выше браузеров. Я не нашел способа применить пространство имен в Chrome.Собирая все вместе, следующий синтаксис работает во всех упомянутых выше браузерах:
.find("row,z\\:row")
источник
Как упоминалось выше, с указанным выше решением существуют проблемы с текущими браузерами / версиями jQuery - предлагаемый плагин не работает полностью из-за проблем с регистром (
nodeName
как свойство, иногда все в верхнем регистре). Итак, я написал следующую быструю функцию:$.findNS = function (o, nodeName) { return o.children().filter(function () { if (this.nodeName) return this.nodeName.toUpperCase() == nodeName.toUpperCase(); else return false; }); };
Пример использования:
$.findNS($(xml), 'x:row');
источник
содержание:
$this.find("content\\:encoded, encoded").text()
идеальное решение ...
источник
Существует плагин jquery-xmlns для jQuery для работы с пространствами имен в селекторах.
источник
Я не видел документации по использованию JQuery для синтаксического анализа XML. JQuery обычно использует Дом браузера для просмотра HTML-документа, я не верю, что он читает сам html.
Вероятно, вам стоит взглянуть на встроенную обработку XML в самом JavaScript.
http://www.webreference.com/programming/javascript/definitive2/
источник
responseXML
свойство встроенногоXMLHttpRequest
объекта, который действительно является XML-документом. Однако jQuery (до 1.5, когдаparseXML
был представлен) не имел возможности синтаксического анализа XML, поэтому Крис был прав.просто заменил пространство имен пустой строкой. У меня отлично работает. Протестированное решение в браузерах: Firefox, IE, Chrome
Моей задачей было прочитать и разобрать EXCEL-файл через Sharepoint EXCEL REST API. XML-ответ содержит теги с пространством имен «x:».
Я решил заменить пространство имен в XML пустой строкой. Работает следующим образом: 1. Получить интересующий узел из XML-ответа 2. Преобразовать XML-ответ (документ) выбранного узла в строку 2. Заменить пространство имен пустой строкой 3. Преобразовать строку обратно в XML-документ
См. Схему кода здесь ->
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 }
Для преобразования XML в String найдите решение здесь: http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string
источник
В качестве альтернативы вы можете использовать в своем проекте fast-xml-parser и преобразовать данные XML в объект JS / JSON. Затем вы можете использовать его как свойство объекта. Он не использует JQuery или другие библиотеки, но решит вашу задачу.
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>
Вы можете игнорировать пространства имен при синтаксическом разборе объекта js / json. В этом случае вы можете получить прямой доступ к as
jsObj.xml.data.row
.for(var i=0; i< jsObj.xml.data.row.length; i++){ console.log(jsObj.xml.data.row[i]); }
Отказ от ответственности : я создал fast-xml-parser.
источник
Для браузеров Webkit вы можете просто опустить двоеточие. Чтобы найти,
<media:content>
например, RSS-канал, вы можете сделать следующее:$(this).find("content");
источник