一个xml格式转换到json格式算法(修正版)
我是个新手,刚工作3个月,写得不对可以提啊,别骂我哦。
在网上找到别人写的一个算法,我也不知道原创在哪里啊,不过还是要注明。我发现这个算法在解析到json时类似下边这样的xml格式解析出来会有问题。
1 <info>
2 <time>2011</time>
3 <school>
4 <loction>美国</loction>
5 <type>大学</type>
6 </school>
7 <frame>
8 <photo>home.jpg</photo>
9 <text>this is one example</text>
10 <ruleinfo>
11 <address>重庆</address>
12 <name>古力</name>
13 </ruleinfo>
14 <ruleinfo>
15 <address>上海</address>
16 <name>姚明</name>
17 </ruleinfo>
18 <ruleinfo>
19 <address>北京</address>
20 <name>jack</name>
21 </ruleinfo>
22 <rule>778</rule>
23 </frame>
24 <frame>
25 <photo>head.jpg</photo>
26 <text>this is another</text>
27 <ruleinfo>
28 <address>北京</address>
29 <name>hello</name>
30 </ruleinfo>
31 <ruleinfo>
32 <address>北京</address>
33 <name>welcome</name>
34 </ruleinfo>
35 <rule>0098</rule>
36 </frame>
37 </info>
我们理论上解析成JSON格式后,school为key值,它的value值应为对象,两个子节点为对象的两个属性,就像这样 "school":{"loction":"美国","type":"大学"}。但实际上解析JSON字符中,不会显示school,就像这样 {"loction":"美国","type":"大学"} ,这显然不是我们希望的,不过只要对该算法稍做处理,还是可以解决的,代码如下
1 /// <summary>
2 /// 转换xml方法
3 /// </summary>
4 /// <param name="xdoc">需转换的xml文档</param>
5 /// <returns>json字符</returns>
6 public string TranXmlToJson(XmlDocument xdoc)
7 {
8 StringBuilder sbJSON = new StringBuilder();
9 sbJSON.Append("{ ");
10 //调用创建节点方法
11 XmlToJSONnode(sbJSON, xdoc.DocumentElement);
12 //结尾,输出
13 sbJSON.Append("}");
14 return sbJSON.ToString();
15 }
16 private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node)
17 {
18 sbJSON.Append("{");
19 Hashtable saveTable = new Hashtable();
20 foreach (XmlNode cnode in node.ChildNodes)
21 {
22 if (cnode.NodeType == XmlNodeType.Element)
23 {
24 StoreChildNode(saveTable, cnode.Name, cnode);
25 }
26 }
27 foreach (string childname in saveTable.Keys)
28 {
29 ArrayList ChildList = (ArrayList)saveTable[childname];
30 //这是我添加上去的代码
31 //集合数量为1,JSON有两种情况,为字符或者为JSON对象
32 if (ChildList.Count == 1)
33 {
34 //集合为字符型,
35 if (ChildList[0] is string||ChildList[0]==null)
36 {
37 OutputNode(childname, ChildList[0], sbJSON, true);
38 }
39 //为JSON对象
40 else
41 {
42 sbJSON.Append(" \"" + SafeJSON(childname) + "\": ");
43 OutputNode(childname, ChildList[0], sbJSON, true);
44 }
45 }
46 //集合数量不为1,JSON中对应JSON数组对象,循环取值
47 else
48 {
49 sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
50 foreach (object Child in ChildList)
51 { OutputNode(childname, Child, sbJSON, false); }
52 sbJSON.Remove(sbJSON.Length - 2, 2);
53 sbJSON.Append(" ], ");
54 }
55 }
56 sbJSON.Remove(sbJSON.Length - 2, 2);
57 sbJSON.Append(" }");
58 }
59
60 private static void StoreChildNode(Hashtable childNodeNames, string nodeName, object nodeValue)
61 {
62 if (nodeValue is XmlElement)
63 {
64 XmlNode cnode = (XmlNode)nodeValue;
65 if( cnode.Attributes.Count == 0)
66 {
67 XmlNodeList children = cnode.ChildNodes;
68 if( children.Count==0)
69 nodeValue = null;
70 else if (children.Count == 1 && (children[0].NodeType==XmlNodeType.Text))
71 nodeValue = children[0].InnerText;
72 }
73 }
74 object oValuesAL = childNodeNames[nodeName];
75 ArrayList ValuesAL;
76 if (oValuesAL == null)
77 {
78 ValuesAL = new ArrayList();
79 childNodeNames[nodeName] = ValuesAL;
80 }
81 else
82 ValuesAL = (ArrayList)oValuesAL;
83 ValuesAL.Add(nodeValue);
84 }
85 private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName)
86 {
87 if (alChild == null)
88 {
89 if (showNodeName)
90 sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
91 sbJSON.Append("\"\"");
92 }
93 else if (alChild is string)
94 {
95 if (showNodeName)
96 sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
97 string sChild = alChild.ToString();
98 sChild = sChild.Trim();
99 sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
100 }
101 else
102 {
103 //sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
104 XmlToJSONnode(sbJSON, (XmlElement)alChild);
105 }
106
107 sbJSON.Append(", ");
108 }
109 private static string SafeJSON(string sIn)
110 {
111 StringBuilder sbOut = new StringBuilder(sIn.Length);
112 foreach (char ch in sIn)
113 {
114 if (Char.IsControl(ch) || ch == '\'')
115 {
116 int ich = (int)ch;
117 sbOut.Append(@"\u" + ich.ToString("x4"));
118 continue;
119 }
120 else if (ch == '\"' || ch == '\\' || ch == '/')
121 {
122 sbOut.Append('\\');
123 }
124 sbOut.Append(ch);
125 }
126 return sbOut.ToString();
127 }
128 }
他的其他地方我做了小小的改动,如果发现有其他地方,各位高手自己修改啊,我就不写了。呵呵