JavaScript实现的XML与JSON互转功能详解


Posted in Javascript onFebruary 16, 2017

本文实例讲述了JavaScript实现的XML与JSON互转功能。分享给大家供大家参考,具体如下:

这里来分享一个关于JavaScript实现XML与JSON互转例子,这里面介绍了国外的三款xml转json的例子,希望这些例子能给你带来帮助。

最近在开发在线XML编辑器,打算使用JSON做为中间格式。因为JSON相对于XML,有着容易阅读、解析速度快、占用空间小等优点,更易于在WEB上传递数据。但在实际使用中还是发现了一些易于忽略的细节,对于需要严格保证XML原始结构的情况,在转换成JSON时需要一些注意。

XML转换成JSON的格式大概如下:

XML形式

<article>
<header id="h1"> 文章标题 </header>
<section id="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>
  <section id="s1">第一节</section>
  <header id="h1"> 标题 </header>
  <section id="s2">第二节</section>
</article>

同样,在一个标签内,它的子标签出现了大于一次,如果需要记录数据的路径,应该使用数组来保存这个结构。正确的代码应该是:

{
  "article": [ {
  "section": {
  "#text": "第一节",
  "@id": "s1"
  },
  }, {
  "header": {
  "#text": "标题",
  "@id": "h1"
  }
  }, {
  "section": {
  "#text": "第一节",
  "@id": "s2"
  }
  }
  ]
}

jkl.parsexml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items>
 <item>
  <zip_cd>10036</zip_cd>
  <us_state>NY</us_state>
  <us_city>New York</us_city>
  <us_dist>Broadway</us_dist>
 </item>
</items>

SAMPLE SCRIPT:

<script type="text/javascript" src="jkl-parsexml.js"></script>
<script><!--
  var url = "zip-e.xml";
  var xml = new JKL.ParseXML( url );
  var data = xml.parse();
  document.write( data["items"]["item"]["us_state"] );
  document.write( data.items.item.us_state );
// --></script>

OUTPUT JSON:

{
 items: {
  item: {
   zip_cd: "1000001"
   us_state: "NY",
   us_city: "New York",
   us_dist: "Broadway",
  }
 }
};

jsonxml

// Changes XML to JSON
function xmlToJson(xml) {
 // Create the return object
 var obj = {};
 if (xml.nodeType == 1) { // element
 // do attributes
 if (xml.attributes.length > 0) {
 obj["@attributes"] = {};
  for (var j = 0; j < xml.attributes.length; j++) {
  var attribute = xml.attributes.item(j);
  obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
  }
 }
 } else if (xml.nodeType == 3) { // text
 obj = xml.nodeValue;
 }
 // do children
 if (xml.hasChildNodes()) {
 for(var i = 0; i < xml.childNodes.length; i++) {
  var item = xml.childNodes.item(i);
  var nodeName = item.nodeName;
  if (typeof(obj[nodeName]) == "undefined") {
  obj[nodeName] = xmlToJson(item);
  } else {
  if (typeof(obj[nodeName].push) == "undefined") {
   var old = obj[nodeName];
   obj[nodeName] = [];
   obj[nodeName].push(old);
  }
  obj[nodeName].push(xmlToJson(item));
  }
 }
 }
 return obj;
};

The major change I needed to implement was using attributes.item(j) instead of the attributes[j] that most of the scripts I found used.  With this function, XML that looks like:

<ALEXA VER="0.9" URL="davidwalsh.name/" HOME="0" AID="=">
 <SD TITLE="A" FLAGS="" HOST="davidwalsh.name">
 <TITLE TEXT="David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else"/>
 <LINKSIN NUM="1102"/>
 <SPEED TEXT="1421" PCT="51"/>
 </SD>
 <SD>
 <POPULARITY URL="davidwalsh.name/" TEXT="7131"/>
 <REACH RANK="5952"/>
 <RANK DELTA="-1648"/>
 </SD>
</ALEXA>

...becomes workable a JavaScript object with the following structure:

{
 "@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: "David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else",
  }
  },
 },
 {
  POPULARITY: {
  "@attributes": {
   TEXT: 7131,
   URL: "davidwalsh.name/"
  }
  },
  RANK: {
  "@attributes": {
   DELTA: "-1648"
  }
  },
  REACH: {
  "@attributes": {
   RANK = 5952
  }
  }
 }
 ]
}

说了半天下面整理了一个例子

function xmlToJson(xml) {
// Create the return object
var obj = {};
if (xml.nodeType == 1) { // element
// do attributes
if (xml.attributes.length > 0) {
obj["@attributes"] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) { // text
obj = xml.nodeValue;
}
// do children
if (xml.hasChildNodes()) {
for (var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (typeof (obj[nodeName]) == "undefined") {
obj[nodeName] = xmlToJson(item);
} else {
if (typeof (obj[nodeName].length) == "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xmlToJson(item));
}
}
}
return obj;
};
Javascript 相关文章推荐
Js如何判断客户端是PC还是手持设备简单分析
Nov 22 Javascript
JS原型对象通俗&quot;唱法&quot;
Dec 27 Javascript
node.js中的fs.rmdirSync方法使用说明
Dec 16 Javascript
JavaScript使用setTimeout实现延迟弹出警告框的方法
Apr 07 Javascript
浅析jquery如何判断滚动条滚到页面底部并执行事件
Apr 29 Javascript
Jquery获取第一个子元素简单实例
Jun 02 Javascript
浅谈js中StringBuffer类的实现方法及使用
Sep 02 Javascript
Bootstrap基本样式学习笔记之图片(6)
Dec 07 Javascript
javascript事件的绑定基础实例讲解(34)
Feb 14 Javascript
对Vue beforeRouteEnter 的next执行时机详解
Aug 25 Javascript
vue+element树组件 实现树懒加载的过程详解
Oct 21 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
Jan 07 Javascript
js实现文字无缝向上滚动
Feb 16 #Javascript
node学习记录之搭建web服务器教程
Feb 16 #Javascript
Angular实现跨域(搜索框的下拉列表)
Feb 16 #Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
Feb 16 #Javascript
js模态对话框使用方法详解
Feb 16 #Javascript
javascript获取以及设置光标位置
Feb 16 #Javascript
JavaScript实现翻页功能(附效果图)
Feb 16 #Javascript
You might like
PHP命名空间(namespace)的动态访问及使用技巧
2014/08/18 PHP
PHP连接SQLServer2005的方法
2015/01/27 PHP
php中mkdir()函数的权限问题分析
2016/09/24 PHP
thinkPHP简单导入和使用阿里云OSSsdk的方法
2017/03/15 PHP
Laravel框架创建路由的方法详解
2019/09/04 PHP
Array对象方法参考
2006/10/03 Javascript
Firefox和IE浏览器兼容JS脚本写法小结
2008/07/07 Javascript
解决js数据包含加号+通过ajax传到后台时出现连接错误
2013/08/01 Javascript
js获取客户端网卡的IP地址、MAC地址
2014/03/26 Javascript
网页运行时提示对象不支持abigimage属性或方法
2014/08/10 Javascript
canvas实现绘制吃豆鱼效果
2017/01/12 Javascript
canvas绘制万花筒效果(代码分享)
2017/01/20 Javascript
jquery实现下拉框左右选择功能
2017/02/21 Javascript
Vue.js中关于侦听器(watch)的高级用法示例
2018/05/02 Javascript
vue添加axios,并且指定baseurl的方法
2018/09/19 Javascript
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
一次让你了解全部JavaScript的作用域
2019/06/24 Javascript
使用VScode 插件debugger for chrome 调试react源码的方法
2019/09/13 Javascript
vuex实现像调用模板方法一样调用Mutations方法
2019/11/06 Javascript
Element DateTimePicker日期时间选择器的使用示例
2020/07/27 Javascript
ant-design表单处理和常用方法及自定义验证操作
2020/10/27 Javascript
详解微信小程序(Taro)手动埋点和自动埋点的实现
2021/03/02 Javascript
[01:53]2016完美“圣”典风云人物:Maybe专访
2016/12/05 DOTA
python映射列表实例分析
2015/01/26 Python
Python使用xlrd读取Excel格式文件的方法
2015/03/10 Python
简单介绍Python的Django框架的dj-scaffold项目
2015/05/30 Python
Python3安装psycopy2以及遇到问题解决方法
2019/07/03 Python
Python命令行参数解析工具 docopt 安装和应用过程详解
2019/09/26 Python
Python多线程:主线程等待所有子线程结束代码
2020/04/25 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
党的群众路线教育实践活动剖析材料
2014/09/30 职场文书
党的群众路线教育实践活动个人对照检查材料(乡镇)
2014/11/05 职场文书
单位接收函范文
2015/01/30 职场文书
行政前台岗位职责
2015/04/16 职场文书
护士工作心得体会
2016/01/25 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS