JavaScript实现的XML与JSON互转功能详解
本文实例讲述了JavaScript实现的XML与JSON互转功能。分享给大家供大家参考,具体如下:
这里来分享一个关于JavaScript实现XML与JSON互转例子,这里面介绍了国外的三款xml转json的例子,希望这些例子能给你带来帮助。
最近在开发在线XML编辑器,打算使用JSON做为中间格式。因为JSON相对于XML,有着容易阅读、解析速度快、占用空间小等优点,更易于在WEB上传递数据。但在实际使用中还是发现了一些易于忽略的细节,对于需要严格保证XML原始结构的情况,在转换成JSON时需要一些注意。
XML转换成JSON的格式大概如下:
XML形式
<article> <headerid="h1">文章标题</header> <sectionid="s1"> <header>章节标题</header> <p>章节段落</p> </section> </article>
JSON表现形式
{ "article":{ "header":{ "#text":"文章标题", "@id":"h1" }, "section":{ "@id":"s1", "header":"章节标题", "p":"章节段落" } } }
用Js将XML转换成JSON的脚本,在网上找了一些现成的脚本,但大都只满足比较简单的情况,都不可以完成保证原始结构的互转。下面是从网上找到的一些脚本或者文章:
x2js :https://code.google.com/p/x2js/
jsonxml:http://davidwalsh.name/convert-xml-json
JKL.ParseXML:http://www.kawa.net/works/js/jkl/parsexml-e.html
x2js不会将下面的XML正确还原。
//XML形式 <p><strong>章节</strong>段<em>落</em></p>
而第2个脚本jsonxml,在上面这种“文本混合标签”的情况下,没有将标签提取出来,而是转换成了下面这种格式。
{"p":"<strong>章节</strong>段<em>落</em>"}}
之后我做了些改动,将它解析成如下格式后,满足了“文本混合标签”可正确还原的情况。
{"p":[{"strong":"章节"},"段",{"em":"落"}]}
另外,形如下面的代码,使用上文提到的脚本进行转换,也会导致无法正确还原的情况。
<article> <sectionid="s1">第一节</section> <headerid="h1">标题</header> <sectionid="s2">第二节</section> </article>
同样,在一个标签内,它的子标签出现了大于一次,如果需要记录数据的路径,应该使用数组来保存这个结构。正确的代码应该是:
{ "article":[{ "section":{ "#text":"第一节", "@id":"s1" }, },{ "header":{ "#text":"标题", "@id":"h1" } },{ "section":{ "#text":"第一节", "@id":"s2" } } ] }
jkl.parsexml
<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?> <items> <item> <zip_cd>10036</zip_cd> <us_state>NY</us_state> <us_city>NewYork</us_city> <us_dist>Broadway</us_dist> </item> </items>
SAMPLESCRIPT:
<scripttype="text/javascript"src="jkl-parsexml.js"></script> <script><!-- varurl="zip-e.xml"; varxml=newJKL.ParseXML(url); vardata=xml.parse(); document.write(data["items"]["item"]["us_state"]); document.write(data.items.item.us_state); //--></script>
OUTPUTJSON:
{ items:{ item:{ zip_cd:"1000001" us_state:"NY", us_city:"NewYork", us_dist:"Broadway", } } };
jsonxml
//ChangesXMLtoJSON functionxmlToJson(xml){ //Createthereturnobject varobj={}; if(xml.nodeType==1){//element //doattributes if(xml.attributes.length>0){ obj["@attributes"]={}; for(varj=0;j<xml.attributes.length;j++){ varattribute=xml.attributes.item(j); obj["@attributes"][attribute.nodeName]=attribute.nodeValue; } } }elseif(xml.nodeType==3){//text obj=xml.nodeValue; } //dochildren if(xml.hasChildNodes()){ for(vari=0;i<xml.childNodes.length;i++){ varitem=xml.childNodes.item(i); varnodeName=item.nodeName; if(typeof(obj[nodeName])=="undefined"){ obj[nodeName]=xmlToJson(item); }else{ if(typeof(obj[nodeName].push)=="undefined"){ varold=obj[nodeName]; obj[nodeName]=[]; obj[nodeName].push(old); } obj[nodeName].push(xmlToJson(item)); } } } returnobj; };
ThemajorchangeIneededtoimplementwasusingattributes.item(j)insteadoftheattributes[j]thatmostofthescriptsIfoundused. Withthisfunction,XMLthatlookslike:
<ALEXAVER="0.9"URL="davidwalsh.name/"HOME="0"AID="="> <SDTITLE="A"FLAGS=""HOST="davidwalsh.name"> <TITLETEXT="DavidWalshBlog::PHP,MySQL,CSS,Javascript,MooTools,andEverythingElse"/> <LINKSINNUM="1102"/> <SPEEDTEXT="1421"PCT="51"/> </SD> <SD> <POPULARITYURL="davidwalsh.name/"TEXT="7131"/> <REACHRANK="5952"/> <RANKDELTA="-1648"/> </SD> </ALEXA>
...becomesworkableaJavaScriptobjectwiththefollowingstructure:
{ "@attributes":{ AID:"=", HOME:0, URL:"davidwalsh.name/", VER:"0.9", }, SD=[ { "@attributes":{ FLAGS:"", HOST:"davidwalsh.name", TITLE:A }, LINKSIN:{ "@attributes":{ NUM:1102 } }, SPEED:{ "@attributes":{ PCT:51, TEXT:1421 } }, TITLE:{ "@attributes":{ TEXT:"DavidWalshBlog::PHP,MySQL,CSS,Javascript,MooTools,andEverythingElse", } }, }, { POPULARITY:{ "@attributes":{ TEXT:7131, URL:"davidwalsh.name/" } }, RANK:{ "@attributes":{ DELTA:"-1648" } }, REACH:{ "@attributes":{ RANK=5952 } } } ] }
说了半天下面整理了一个例子
functionxmlToJson(xml){ //Createthereturnobject varobj={}; if(xml.nodeType==1){//element //doattributes if(xml.attributes.length>0){ obj["@attributes"]={}; for(varj=0;j<xml.attributes.length;j++){ varattribute=xml.attributes.item(j); obj["@attributes"][attribute.nodeName]=attribute.nodeValue; } } }elseif(xml.nodeType==3){//text obj=xml.nodeValue; } //dochildren if(xml.hasChildNodes()){ for(vari=0;i<xml.childNodes.length;i++){ varitem=xml.childNodes.item(i); varnodeName=item.nodeName; if(typeof(obj[nodeName])=="undefined"){ obj[nodeName]=xmlToJson(item); }else{ if(typeof(obj[nodeName].length)=="undefined"){ varold=obj[nodeName]; obj[nodeName]=[]; obj[nodeName].push(old); } obj[nodeName].push(xmlToJson(item)); } } } returnobj; };
PS:这里再为大家提供几款关于xml与json操作的在线工具供大家参考使用:
在线