用JQuery与CDATA解析XML。

时间:2021-08-07 08:56:41

Edit: I was missing two things here. The lack of "Content-Type:text/xml" in the header returned by the AJAX call was preventing JQuery from treating the returned data as a document. Once that was handled correctly, this code parsed correctly and output just the index and project name.

编辑:我漏掉了两件事。AJAX调用返回的头中缺少“内容类型:text/xml”,这阻止了JQuery将返回的数据作为文档处理。一旦处理得当,此代码将正确解析并输出索引和项目名称。

$("a.getprojects").click(function(d){
  d.preventDefault();
  var api_token = $("#token").val();
  var form_fbod = $("#fbod").val();
  $.post("fbinfo.php", {fbod: form_fbod, token: api_token, cmd : 'listProjects', extra:''}, function(returned_xml) {
    var output = '';
    $(returned_xml).find("project").each(function(){
      var project = $(this);
      output += project.find("ixProject").text();
      output += " ";
      output += project.find("sProject").text();
      output += "\n";
    });
    $("#output").val(output);
  });
});

Original: I'm having fun using the FogBugz API and JQuery to put together what I think will be a cool little tool, but I'm running into a JQuery limitation. CDATA tags seem to confuse it.

最初:我使用FogBugz API和JQuery来组装我认为将会是一个很酷的小工具,但是我遇到了JQuery的限制。CDATA标签似乎混淆了它。

Here's the code I'm using:

下面是我使用的代码:

  $("a.getprojects").click(function(d){
    d.preventDefault();
    var api_token = $("#token").val();
    var form_fbod = $("#fbod").val();
    $.post("fbinfo.php", {fbod: form_fbod, token: api_token, cmd : 'listProjects', extra:''}, function(xml) {
      var output = xml;
      $(xml).find("project").each(function(){
        var project = $(this);
        output += "\n\n";

        output += project.html();

      });
      $("#output").val(output);

    });
  });

And here 's the output I get:

这是我得到的输出:

<?xml version="1.0" encoding="UTF-8"?><response>
    <projects>
<project>
<ixProject>2</ixProject>
<sProject><![CDATA[Inbox]]></sProject>
<ixPersonOwner>2</ixPersonOwner>
<sPersonOwner><![CDATA[Rich]]></sPersonOwner>
<sEmail><![CDATA[rich@example.com]]></sEmail>
<sPhone></sPhone>
<fInbox>true</fInbox>
<ixGroup>1</ixGroup>
<iType>1</iType>
<sGroup><![CDATA[Internal]]></sGroup>
</project>

<project>
<ixProject>1</ixProject>
<sProject><![CDATA[Sample Project]]></sProject>
<ixPersonOwner>2</ixPersonOwner>
<sPersonOwner><![CDATA[Rich]]></sPersonOwner>
<sEmail><![CDATA[rich@example.com]]></sEmail>
<sPhone></sPhone>
<fInbox>false</fInbox>
<ixGroup>1</ixGroup>
<iType>1</iType>
<sGroup><![CDATA[Internal]]></sGroup>
</project>
</projects>
</response>

<ixproject>2</ixproject>
<sproject></sproject>
<ixpersonowner>2</ixpersonowner>
<spersonowner></spersonowner>
<semail></semail>
<sphone></sphone>
<finbox>true</finbox>
<ixgroup>1</ixgroup>
<itype>1</itype>
<sgroup></sgroup>

<ixproject>1</ixproject>
<sproject></sproject>
<ixpersonowner>2</ixpersonowner>
<spersonowner></spersonowner>
<semail></semail>
<sphone></sphone>
<finbox>false</finbox>
<ixgroup>1</ixgroup>
<itype>1</itype>
<sgroup></sgroup>

It would seem that the XML parsing that's native to JQuery discards the contents of CDATA elements. FogBugz puts most of our string data in CDATA tags because we allow special characters and punctuation in most places. Enclosing the output in CDATA tags allows us to rest relatively assured that we're sending back valid data via our API. PHP parsing of the XML works just fine. My research online yields a few people complaining about this, but not much work getting done. With JQuery's extensibility, I would think that there's something out there. Has anyone else accomplished this?

看起来,本机到JQuery的XML解析会丢弃CDATA元素的内容。FogBugz将大部分字符串数据放在CDATA标记中,因为我们允许在大多数地方使用特殊的字符和标点符号。将输出封装在CDATA标记中可以使我们相对放心地通过API发送有效数据。XML的PHP解析非常有效。我在网上的研究引起了一些人的抱怨,但并没有太多的工作要做。有了JQuery的可扩展性,我认为还有其他的东西。还有其他人完成了吗?

2 个解决方案

#1


14  

It would seem that the XML parsing that's native to JQuery

看起来XML解析是JQuery原生的

There is no XML parsing native to jQuery. It just uses the standard XMLHttpRequest.responseXML property to get an XML DOM for the response.

jQuery没有原生的XML解析。它只使用标准的XMLHttpRequest。responseXML属性获取响应的XML DOM。

discards the contents of CDATA elements

丢弃CDATA元素的内容

What Content-Type are you sending the response with? Because I suspect it's not being parsed as XML at all. In this case jQuery will be passing you back a string of the document, instead of an XML DOM.

发送响应的内容类型是什么?因为我怀疑它根本没有被解析为XML。在这种情况下,jQuery将传递给您文档的字符串,而不是XML DOM。

Then when you call “$(xml)”, it will be creating document content from that string(*) — parsed as HTML, not XML. In HTML there is no such thing as a CDATA section, so browsers might discard them, or treat them as comments.

然后当您调用“$(xml)”时,它将从该字符串(*)创建文档内容——解析为HTML,而不是xml。在HTML中不存在CDATA部分,因此浏览器可能会丢弃它们,或者将它们视为注释。

I suspect this because “project.html()” shouldn't actually work when the document is XML. ‘html()’ just returns the same as the standard ‘innerHTML’ property(**), which only works for HTML documents; it is undefined on XML elements.

我怀疑这是因为“project.html()”在文档是XML时实际上不应该工作。“html()”返回的是标准的“innerHTML”属性(**),它只对html文档有效;它在XML元素上没有定义。

Enclosing the output in CDATA tags allows us to rest relatively assured that we're sending back valid data via our API.

将输出封装在CDATA标记中可以使我们相对放心地通过API发送有效数据。

Well, ‘relatively’: if your data happens to contain “]]>” you still lose. <![CDATA[ sections are intended as a crutch to improve writability for hand authoring; machine-generated XML should really just use entity-encoding in the normal fashion. Usually the server app should be using proper XML tools to generate the response in which case this will be done automatically.

嗯,“相对”:如果你的数据碰巧包含“]>”,你还是会输。< ![CDATA]章节的目的是为了提高手写性;机器生成的XML实际上应该以正常的方式使用实体编码。通常,服务器应用程序应该使用适当的XML工具来生成响应,在这种情况下,响应将自动完成。

(*: I have never understood when jQuery feels the need to squish document fragment creation and CSS selection into the same function. They're completely different operations which you don't want to get confused, as may have happened here.)

(*:我从未理解jQuery何时需要将文档片段创建和CSS选择压缩到同一个函数中。它们是完全不同的操作,你不想弄混,就像这里发生的那样。

(**: Actually, it tries to filter out jQuery custom attributes first, using a regex. Unfortunately since regex cannot parse HTML, it will happily filter out valid parts of your text that happen to look like HTML attributes. Whoops. Not one of jQuery's prettier parts.)

(**:实际上,它尝试首先使用正则表达式过滤jQuery自定义属性。不幸的是,由于regex不能解析HTML,它会很高兴地过滤掉文本中看起来像HTML属性的有效部分。哎呦。jQuery没有一个更漂亮的部分)

#2


6  

jquery does in fact have an xml parser now that should solve your problem. $.parseXML(xml) http://api.jquery.com/jQuery.parseXML/

jquery实际上已经有了一个xml解析器,可以解决您的问题。美元.parseXML(xml)http://api.jquery.com/jQuery.parseXML/

#1


14  

It would seem that the XML parsing that's native to JQuery

看起来XML解析是JQuery原生的

There is no XML parsing native to jQuery. It just uses the standard XMLHttpRequest.responseXML property to get an XML DOM for the response.

jQuery没有原生的XML解析。它只使用标准的XMLHttpRequest。responseXML属性获取响应的XML DOM。

discards the contents of CDATA elements

丢弃CDATA元素的内容

What Content-Type are you sending the response with? Because I suspect it's not being parsed as XML at all. In this case jQuery will be passing you back a string of the document, instead of an XML DOM.

发送响应的内容类型是什么?因为我怀疑它根本没有被解析为XML。在这种情况下,jQuery将传递给您文档的字符串,而不是XML DOM。

Then when you call “$(xml)”, it will be creating document content from that string(*) — parsed as HTML, not XML. In HTML there is no such thing as a CDATA section, so browsers might discard them, or treat them as comments.

然后当您调用“$(xml)”时,它将从该字符串(*)创建文档内容——解析为HTML,而不是xml。在HTML中不存在CDATA部分,因此浏览器可能会丢弃它们,或者将它们视为注释。

I suspect this because “project.html()” shouldn't actually work when the document is XML. ‘html()’ just returns the same as the standard ‘innerHTML’ property(**), which only works for HTML documents; it is undefined on XML elements.

我怀疑这是因为“project.html()”在文档是XML时实际上不应该工作。“html()”返回的是标准的“innerHTML”属性(**),它只对html文档有效;它在XML元素上没有定义。

Enclosing the output in CDATA tags allows us to rest relatively assured that we're sending back valid data via our API.

将输出封装在CDATA标记中可以使我们相对放心地通过API发送有效数据。

Well, ‘relatively’: if your data happens to contain “]]>” you still lose. <![CDATA[ sections are intended as a crutch to improve writability for hand authoring; machine-generated XML should really just use entity-encoding in the normal fashion. Usually the server app should be using proper XML tools to generate the response in which case this will be done automatically.

嗯,“相对”:如果你的数据碰巧包含“]>”,你还是会输。< ![CDATA]章节的目的是为了提高手写性;机器生成的XML实际上应该以正常的方式使用实体编码。通常,服务器应用程序应该使用适当的XML工具来生成响应,在这种情况下,响应将自动完成。

(*: I have never understood when jQuery feels the need to squish document fragment creation and CSS selection into the same function. They're completely different operations which you don't want to get confused, as may have happened here.)

(*:我从未理解jQuery何时需要将文档片段创建和CSS选择压缩到同一个函数中。它们是完全不同的操作,你不想弄混,就像这里发生的那样。

(**: Actually, it tries to filter out jQuery custom attributes first, using a regex. Unfortunately since regex cannot parse HTML, it will happily filter out valid parts of your text that happen to look like HTML attributes. Whoops. Not one of jQuery's prettier parts.)

(**:实际上,它尝试首先使用正则表达式过滤jQuery自定义属性。不幸的是,由于regex不能解析HTML,它会很高兴地过滤掉文本中看起来像HTML属性的有效部分。哎呦。jQuery没有一个更漂亮的部分)

#2


6  

jquery does in fact have an xml parser now that should solve your problem. $.parseXML(xml) http://api.jquery.com/jQuery.parseXML/

jquery实际上已经有了一个xml解析器,可以解决您的问题。美元.parseXML(xml)http://api.jquery.com/jQuery.parseXML/