使用命名空间进行jQuery XML解析

时间:2009-05-12 16:46:50

标签: javascript jquery xml namespaces xsd

我是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 个答案:

答案 0 :(得分:131)

我明白了。

事实证明它需要\\来逃避冒号。

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

正如Rich指出的那样:

更好的解决方案不需要转义并适用于所有“现代”浏览器:

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

答案 1 :(得分:35)

我花了几个小时阅读关于插件和各种解决方案的阅读,但没有运气。

ArnisAndy发布了jQuery讨论的链接,提供了这个答案,我可以确认这适用于Chrome(v18.0),FireFox(v11.0),IE(v9.08)和Safari( v5.1.5)使用jQuery(v1.7.2)。

我正在尝试抓取一个名为&lt; content:encoded&gt;的内容的WordPress Feed这对我有用:

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

答案 2 :(得分:20)

如果您使用的是jquery 1.5,则必须在节点选择器属性值周围添加引号以使其正常工作:

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

答案 3 :(得分:19)

虽然上面的答案似乎是正确的,但它在webkit浏览器(Safari,Chrome)中不起作用。我认为更好的解决方案是:

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

答案 4 :(得分:15)

如果有人需要这样做没有jQuery ,只需要使用普通的Javascript,对于谷歌Chrome(webkit),这是我发现获取它的唯一方法经过大量的研究和测试后才能工作。

  

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

这将用于检索以下节点:<prefix:name>。如您所见,前缀或名称空间被省略,并且它将匹配具有不同名称空间的元素,前提是标记名称为name。但希望这对你来说不是问题。

这些都不适用于我(我正在开发Google Chrome扩展程序):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

编辑 :经过一段时间的休眠后,我找到了一种有效的解决方法 :)此函数返回匹配完整{{1}的第一个节点例如nodeName

<prefix:name>

如果您需要返回所有匹配元素,可以轻松修改它。希望它有所帮助!

答案 5 :(得分:14)

上述解决方案均无效。我发现了这个并且速度有所提高。只需添加它,就像一个魅力:

$.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/

答案 6 :(得分:9)

“\\”逃脱不是万无一失的简单

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

从Jquery 1.7开始,方法似乎已被破坏。我能够在这里使用过滤函数找到1.7的解决方案:Improving Javascript XML Node Finding Performance

答案 7 :(得分:3)

值得注意的是,从jQuery 1.7开始,一些解决命名空间元素的方法存在问题。有关更多信息,请参阅以下链接:

答案 8 :(得分:3)

在评论中找到解决方案:Parsing XML with namespaces using jQuery $().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

答案 9 :(得分:2)

我的解决方案(因为我使用的是Php代理)是用_替换:namespace ...所以没有更多的命名空间问题; - )

保持简单!

答案 10 :(得分:2)

从2016年初开始,对我来说,以下语法适用于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")

语法.find("[nodeName=z:row]")在上述任何浏览器中都不起作用。我发现无法在Chrome中应用命名空间。

总而言之,以下语法适用于上述所有浏览器:.find("row,z\\:row")

答案 11 :(得分:2)

原始答案:jQuery XML parsing how to get element attribute

以下是如何在Chrome中成功获取值的示例..

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

答案 12 :(得分:2)

jQuery 1.7不适用于以下内容:

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

我在Chrome,Firefox和IE中使用的一个解决方案是使用在IE中工作的选择器和在Chrome中工作的选择器,基于以下事实:一种方式适用于IE,另一种适用于Chrome:< / p>

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

在IE中,这将返回使用命名空间的节点(Firefox和IE需要命名空间),而在Chrome中,选择器根据非命名空间选择器返回节点。我没有在Safari中对此进行测试,但它应该可以正常工作,因为它在Chrome中运行。

答案 13 :(得分:1)

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

是完美的解决方案......

答案 14 :(得分:1)

如上所述,使用当前浏览器/ 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');

答案 15 :(得分:1)

jQuery有一个插件jquery-xmlns可以在选择器中使用命名空间。

答案 16 :(得分:0)

刚用空字符串替换了命名空间。对我来说很好。跨浏览器的经过测试的解决方案:Firefox,IE,Chrome

我的任务是通过Sharepoint EXCEL REST API读取和解析EXCEL文件。 XML响应包含带有“x:”命名空间的标记。

我决定用空字符串替换XML中的命名空间。这样工作: 1.从XML响应中获取感兴趣的节点 2.将选定节点XML-Response(Document)转换为String 2.用空字符串替换命名空间 3.将字符串转换回XML-Document

请参阅此处的代码大纲 - &gt;

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-to-String转换,请在此处找到解决方案: http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string

答案 17 :(得分:0)

我还没有看到任何关于使用JQuery来解析XML的文档。 JQuery通常使用Browser dom来浏览HTML文档,我不相信它会读取html本身。

你应该看看JavaScript本身的内置XML处理。

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

答案 18 :(得分:0)

或者,您可以在项目中使用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对象时忽略名称空间。在这种情况下,您可以直接访问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。

答案 19 :(得分:-1)

对于Webkit浏览器,您可以不用冒号。因此,要在RSS Feed中查找<media:content>,您可以执行以下操作:

$(this).find("content");