jQuery XML与命名空间解析
我是新来的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");
真的没有运气。 有任何想法吗? 谢谢。
我知道了。
原来,它需要\\
来逃避冒号。
$.get(xmlPath, {}, function(xml) { $("rs\\:data", xml).find("z\\:row").each(function(i) { alert("found zrow"); }); }, "xml");
正如Rich指出的那样:
更好的解决方案不需要转义,可以在所有“现代”浏览器上运行:
.find("[nodeName=z:row]")
我已经花了几个小时阅读关于插件和各种解决方案,没有运气。
ArnisAndy发布了一个jQuery讨论链接,提供了这个答案,我可以确认这适用于Chrome(v18.0),FireFox(v11.0),IE(v9.08)和Safari(v5.1.5) )使用jQuery(v1.7.2)。
我试图抓取内容被命名为<content:encoded>的WordPress提要,这对我来说是有效的:
content: $this.find("content\\:encoded, encoded").text()
如果您正在使用jQuery 1.5,您将不得不围绕节点选择器属性值添加引号以使其工作:
.find('[nodeName="z:row"]')
虽然上面的答案似乎是正确的,但它不适用于webkit浏览器(Safari,Chrome)。 我相信一个更好的解决方案是:
.find("[nodeName=z:myRow, myRow]")
如果有人需要不使用jQuery ,只使用普通的Javascript和谷歌浏览器(webkit)来做到这一点,这是我经过大量的研究和测试后才发现的。
parentNode.getElementsByTagNameNS("*", "name");
这将用于检索以下节点: <prefix:name>
。 正如你所看到的,前缀或名字空间被省略,并且它将匹配具有不同名字空间的元素,只要标签名称是name
。 但是,希望这不会成为你的问题。
这一切都没有为我工作 (我正在开发一个谷歌浏览器扩展):
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的解决方案,使用过滤器功能,在这里: 提高Javascript XML节点寻找性能
值得注意的是,从jQuery 1.7开始,在寻找命名空间元素方面存在一些问题。 请参阅以下链接了解更多信息:
- jQuery Bug Ticket注意到缺少跨浏览器支持的能力.find('[nodeName =“z:row”]')
- 建议使用一些性能测试的插件解决方法。
在评论中找到解决方案: 使用jQuery解析名称空间的XML $()。find
在冒号为我工作之后使用节点名称的后半部分。 使用.find(“lat”)而不是.find(“geo \:lat”) ,它为我工作。
我的设置:
- Chrome 42
- jQuery 2.1.3
示例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中运行,
$(xml).find('a\\\\:IndexField2, IndexField2')
在IE中,这将返回使用名称空间(Firefox和IE需要名称空间)的节点,而在Chrome中,选择器将基于非名称空间选择器返回节点。 我没有在Safari中测试过,但它应该可以工作,因为它在Chrome中工作。
我的解决方案(因为我使用一个PHP代理)是用_替换:命名空间,所以没有更多的命名空间问题;-)
把事情简单化 !
原始答案: jQuery XML解析如何获取元素属性
以下是如何成功获取Chrome中的值的示例
item.description = jQuery(this).find("[nodeName=itunes\\:summary]").eq(0).text();
如上所述,使用当前浏览器/ 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()
是完美的解决方案…
截至2016年初,对我来说,以下语法适用于jQuery 1.12.0:
- IE 11(11.0.9600.18204,更新11.0.28,KB3134815)
.find("z\\:row")
- Firefox 44.0.2:
.find("z\\:row")
- Chrome 44.0.2403.89m:
.find("row")
语法.find("[nodeName=z:row]")
在上述任何浏览器中都不起作用。 我发现没有办法在Chrome中应用命名空间。
综合起来,以下语法适用于上面提到的所有浏览器: .find("row,z\\:row")
有一个插件jquery-xmlns让jQuery能够在选择器中使用命名空间。
我还没有看到使用JQuery解析XML的任何文档。 JQuery通常使用Browser dom来浏览一个HTML文档,我不相信它会读取html本身。
你可能应该看看JavaScript本身的内置XML处理。
http://www.webreference.com/programming/javascript/definitive2/
只是用空字符串替换了命名空间。 为我工作得很好。 跨浏览器测试的解决方案:Firefox,IE,Chrome
我的任务是通过Sharepoint EXCEL REST API读取和解析EXCEL文件。 XML响应包含具有“x:”名称空间的标签。
我决定用空字符串替换XML中的名称空间。 以这种方式工作:1.从XML响应中获取感兴趣的节点2.将所选节点XML-Response(Document)转换为字符串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到字符串的转换在这里找到一个解决方案: http : //www.sencha.com/forum/showthread.php?34553 -Convert-DOM-XML-Document-to-string
对于Webkit浏览器,您可以忽略冒号。 所以要找到RSS feed中的<media:content>
,你可以这样做:
$(this).find("content");