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操作的在线工具供大家参考使用:
在线