您的位置:首页 > Web前端 > JavaScript

一个xml格式转换到json格式算法(修正版)

2011-10-24 20:40 190 查看
我是个新手,刚工作3个月,写得不对可以提啊,别骂我哦。

在网上找到别人写的一个算法,我也不知道原创在哪里啊,不过还是要注明。我发现这个算法在解析到json时类似下边这样的xml格式解析出来会有问题。

<info>
<time>2011</time>
<school>
<loction>美国</loction>
<type>大学</type>
</school>
<frame>
<photo>home.jpg</photo>
<text>this is one example</text>
<ruleinfo>
<address>重庆</address>
<name>古力</name>
</ruleinfo>
<ruleinfo>
<address>上海</address>
<name>姚明</name>
</ruleinfo>
<ruleinfo>
<address>北京</address>
<name>jack</name>
</ruleinfo>
<rule>778</rule>
</frame>
<frame>
<photo>head.jpg</photo>
<text>this is another</text>
<ruleinfo>
<address>北京</address>
<name>hello</name>
</ruleinfo>
<ruleinfo>
<address>北京</address>
<name>welcome</name>
</ruleinfo>
<rule>0098</rule>
</frame>
</info>


我们理论上解析成JSON格式后,school为key值,它的value值应为对象,两个子节点为对象的两个属性,就像这样 "school":{"loction":"美国","type":"大学"}。但实际上解析JSON字符中,不会显示school,就像这样 {"loction":"美国","type":"大学"} ,这显然不是我们希望的,不过只要对该算法稍做处理,还是可以解决的,代码如下

/// <summary>
/// 转换xml方法
/// </summary>
/// <param name="xdoc">需转换的xml文档</param>
/// <returns>json字符</returns>
public string TranXmlToJson(XmlDocument xdoc)
{
StringBuilder sbJSON = new StringBuilder();
sbJSON.Append("{ ");
//调用创建节点方法
XmlToJSONnode(sbJSON, xdoc.DocumentElement);
//结尾,输出
sbJSON.Append("}");
return sbJSON.ToString();
}
private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node)
{
sbJSON.Append("{");
Hashtable saveTable = new Hashtable();
foreach (XmlNode cnode in node.ChildNodes)
{
if (cnode.NodeType == XmlNodeType.Element)
{
StoreChildNode(saveTable, cnode.Name, cnode);
}
}
foreach (string childname in saveTable.Keys)
{
ArrayList ChildList = (ArrayList)saveTable[childname];
//这是我添加上去的代码
//集合数量为1,JSON有两种情况,为字符或者为JSON对象
if (ChildList.Count == 1)
{
//集合为字符型,
if (ChildList[0] is string||ChildList[0]==null)
{
OutputNode(childname, ChildList[0], sbJSON, true);
}
//为JSON对象
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\":  ");
OutputNode(childname, ChildList[0], sbJSON, true);
}
}
//集合数量不为1,JSON中对应JSON数组对象,循环取值
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
foreach (object Child in ChildList)
{ OutputNode(childname, Child, sbJSON, false); }
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" ], ");
}
}
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" }");
}

private static void StoreChildNode(Hashtable childNodeNames, string nodeName, object nodeValue)
{
if (nodeValue is XmlElement)
{
XmlNode cnode = (XmlNode)nodeValue;
if( cnode.Attributes.Count == 0)
{
XmlNodeList children = cnode.ChildNodes;
if( children.Count==0)
nodeValue = null;
else if (children.Count == 1 && (children[0].NodeType==XmlNodeType.Text))
nodeValue = children[0].InnerText;
}
}
object oValuesAL = childNodeNames[nodeName];
ArrayList ValuesAL;
if (oValuesAL == null)
{
ValuesAL = new ArrayList();
childNodeNames[nodeName] = ValuesAL;
}
else
ValuesAL = (ArrayList)oValuesAL;
ValuesAL.Add(nodeValue);
}
private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName)
{
if (alChild == null)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
sbJSON.Append("\"\"");
}
else if (alChild is string)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
string sChild = alChild.ToString();
sChild = sChild.Trim();
sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
}
else
{
//sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
XmlToJSONnode(sbJSON, (XmlElement)alChild);
}

sbJSON.Append(", ");
}
private static string SafeJSON(string sIn)
{
StringBuilder sbOut = new StringBuilder(sIn.Length);
foreach (char ch in sIn)
{
if (Char.IsControl(ch) || ch == '\'')
{
int ich = (int)ch;
sbOut.Append(@"\u" + ich.ToString("x4"));
continue;
}
else if (ch == '\"' || ch == '\\' || ch == '/')
{
sbOut.Append('\\');
}
sbOut.Append(ch);
}
return sbOut.ToString();
}
}


他的其他地方我做了小小的改动,如果发现有其他地方,各位高手自己修改啊,我就不写了。呵呵
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: