在xml转json时,理论上可以转换所有的xml文件。看到有很多其他博主写的代码很好,但是没有写清楚程序的思路是什么,正好最近工作用到这一部分内容,研究了一会,添加了获取xml标签内属性的方法。现在就整理一下转换的思路,以便以后再用到能快速拾起,如果能正好帮助到需要的人会十分高兴,不足的地方想到了再补充。
用到的jar包:
jdom ,fastjson(alibaba)
转换思路:
步骤如下:
1.将xml文件转换成字符串,可通过读取xml文件获取,再转换成Decument。转换Decument时,要先将xml文件转换为流的形式,编码方式为utf-8,防止中文乱码。
2.调用Decument的方法,获取根节点,并遍历节点内所有子节点,把每个节点转换为JSONObject.
3.遍历时,节点的属性和节点下的子节点在同一级,属性在前,子节点在后。若有多个属性或子节点,则包装成一个list,再加入最外层的JSONObject内。
遍历标签的思路:
1.先设置一次循环,循环的次数为根节点下子节点的个数。
2.判断当前节点内是否包含属性值,如果包含,则将属性值全部取出放入list内,遍历这个list,取出属性的名字和值加入到JSONObject,最后加入到list中。一个元素属性值和他的子元素的值是同一等级。
3.判断当前元素内是否还有其他的子元素,若有将当前元素作为根元素递归调用遍历方法。
4.当在一个JSONObject中添加了一个节点的属性后,再添加这个节点的子节点时,要把之前的节点选择出来再进行拓展。
java代码如下:
public class JsonParse2 {
public static String xml2JSON(String xml) {
JSONObject json = new JSONObject();
byte[] byteStream = null;
try {
byteStream = xml.getBytes("utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
InputStream is = new ByteArrayInputStream(byteStream);
SAXBuilder sb = new SAXBuilder();
org.jdom.Document doc = null;
try {
doc = sb.build(is);
} catch (JDOMException | IOException e) {
e.printStackTrace();
}
Element root = doc.getRootElement();
json.put(root.getName(), iterateElement(root));
String jsonString = json.toJSONString();
return jsonString;
}
private static JSONObject iterateElement(Element element) {
List<Element> node = element.getChildren();
Element et = null;
JSONObject obj = new JSONObject();
//其内的值可能为一个元素,也可能为一个list,故不设泛型
List list = null;
//遍历当前元素
for (int i = 0; i < node.size(); i++) {
list = new LinkedList<>();
et = (Element) node.get(i);
//获取元素内的属性
if (et.getAttributes().size() > 0) {
//获取当前元素的所有的属性值
List<Attribute> attributes = et.getAttributes();
//每一个属性都是一个jsonobject
JSONObject attrvalue = new JSONObject();
//属性值最终要合成的list
List<JSONObject> attrvalues = new ArrayList<>();
for (Attribute attr : attributes) {
//将参数的名和值封装为一个jsonobject
attrvalue.put(attr.getName(),attr.getValue());
}
attrvalues.add(attrvalue);
obj.put(et.getName(), attrvalues);
}
//判断元素是否为空
if (et.getTextTrim().equals("")) {
if (et.getChildren().size() == 0)
continue;
//判断obj内是否有与当前元素重名的元素
if (obj.containsKey(et.getName())) {
//若存在,就在之前的list后拓展
list = (List<JSONObject>) obj.get(et.getName());
}
list.add(iterateElement(et));
obj.put(et.getName(), list);
} else {
if (obj.containsKey(et.getName())) {
list = (List<JSONObject>) obj.get(et.getName());
}
list.add(et.getTextTrim());
obj.put(et.getName(), list);
}
}
return obj;
}
}
测试用例:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<m:PlaceOrder_LocalInput xmlns:m="http://siebel.com/">
<PlaceOrder_LocalInput m:loid="111">
<AccountNum>202138621209</AccountNum>
<ContactId>1234</ContactId>
<ContactPhone>+8612341234</ContactPhone>
</PlaceOrder_LocalInput>
</m:PlaceOrder_LocalInput>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
测试结果:
{
"Envelope": {
"Body": [{
"PlaceOrder_LocalInput": [{
"PlaceOrder_LocalInput": [{
"loid": "111"
}, {
"AccountNum": ["202138621209"],
"ContactPhone": ["+8612341234"],
"ContactId": ["1234"]
}]
}]
}]
}
}