我开始使用Json.NET将JSON格式的字符串转换为对象,或者反过来。我不确定在Json.NET框架中是否可以将JSON格式的字符串转换为XML格式,或者反之亦然?
是的,可以使用JsonConvert类,该类包含用于此特定目的的帮助方法:
// To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
文档在这里:使用Json.NET将JSON和XML相互转换
是的,你可以这样做(我也这么做),但要注意在转换时可能会出现一些悖论,并进行适当处理。您不能自动符合所有接口可能性,并且在控制转换方面具有有限的内置支持-许多JSON结构和值不能自动双向转换。请记住,我正在使用Newtonsoft JSON库和MS XML库的默认设置,因此结果可能会有所不同:
{}
或嵌套数组[ {} {} ...]
,具体取决于是否只有一个或多个XML子元素。您将以不同的方式在JavaScript等中使用这两种类型。符合相同模式的不同XML示例可以以这种方式产生实际上不同的JSON结构。您可以为元素添加属性json:Array='true',以在某些情况下解决此问题(但不一定适用于所有情况)。一项新的更新改变了如何处理null(感谢Jon Story指出):https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
请随时提及您注意到的任何其他问题,我已经开发了自己的自定义程序来准备和清理字符串,以便在JSON和XML之间进行转换。您的情况可能需要预处理/清理,也可能不需要。正如StaxMan所提到的那样,您的情况可能实际上需要在对象之间进行转换......这可能涉及适当的接口以及大量的case语句/等,以处理我上面提到的细节。
你也可以使用 .NET Framework 进行以下转换:
JSON 到 XML:通过使用 System.Runtime.Serialization.Json
var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));
XML转JSON:通过使用System.Web.Script.Serialization。
var json = new JavaScriptSerializer().Serialize(GetXmlData(XElement.Parse(xmlString)));
private static Dictionary<string, object> GetXmlData(XElement xml)
{
var attr = xml.Attributes().ToDictionary(d => d.Name.LocalName, d => (object)d.Value);
if (xml.HasElements) attr.Add("_value", xml.Elements().Select(e => GetXmlData(e)));
else if (!xml.IsEmpty) attr.Add("_value", xml.Value);
return new Dictionary<string, object> { { xml.Name.LocalName, attr } };
}
json.net
,后来他甚至回答了这个问题https://dev59.com/LXRA5IYBdhLWcg3wzhfZ#816095所以假设“不确定...正在尝试一些库”是错误的。尽管如果第一个尝试与`json.net`上下文相关,那么这可以成为另一种答案,就像这里https://dev59.com/LXRA5IYBdhLWcg3wzhfZ#814027。 - Vinod Srivastav我不确定进行这样的转换是否有意义(是的,许多人这么做,但大多数情况下是为了将方形钉子塞进圆孔)- 存在结构性阻抗失配,并且转换是有损的。因此,我建议不要进行格式到格式的转换。
但是如果您真的需要这么做,请先将 JSON 转换为对象,然后再将对象转换为 XML(反向转换也是如此)。直接进行转换会导致丑陋的输出,信息的丢失或可能两者都有。
感谢David Brown的答案。在我使用JSON.Net 3.5的情况下,转换方法在JsonConvert静态类中:
XmlNode myXmlNode = JsonConvert.DeserializeXmlNode(myJsonString); // is node not note
// or .DeserilizeXmlNode(myJsonString, "root"); // if myJsonString does not have a root
string jsonString = JsonConvert.SerializeXmlNode(myXmlNode);
我花了很长时间寻找替代代码,以期不使用外部程序集/项目。在查看DynamicJson项目的源代码后,我想到了以下解决方案:
public XmlDocument JsonToXML(string json)
{
XmlDocument doc = new XmlDocument();
using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), XmlDictionaryReaderQuotas.Max))
{
XElement xml = XElement.Load(reader);
doc.LoadXml(xml.ToString());
}
return doc;
}
注意:出于XPath的目的,我希望使用XmlDocument而不是XElement。
此外,这段代码显然只能将JSON转换为XML,有各种方法可以做相反的转换。
以下是完整的C#代码,可用于将XML转换为JSON:
public static class JSon
{
public static string XmlToJSON(string xml)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
return XmlToJSON(doc);
}
public static string XmlToJSON(XmlDocument xmlDoc)
{
StringBuilder sbJSON = new StringBuilder();
sbJSON.Append("{ ");
XmlToJSONnode(sbJSON, xmlDoc.DocumentElement, true);
sbJSON.Append("}");
return sbJSON.ToString();
}
// XmlToJSONnode: Output an XmlElement, possibly as part of a higher array
private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
sbJSON.Append("{");
// Build a sorted list of key-value pairs
// where key is case-sensitive nodeName
// value is an ArrayList of string or XmlElement
// so that we know whether the nodeName is an array or not.
SortedList<string, object> childNodeNames = new SortedList<string, object>();
// Add in all node attributes
if (node.Attributes != null)
foreach (XmlAttribute attr in node.Attributes)
StoreChildNode(childNodeNames, attr.Name, attr.InnerText);
// Add in all nodes
foreach (XmlNode cnode in node.ChildNodes)
{
if (cnode is XmlText)
StoreChildNode(childNodeNames, "value", cnode.InnerText);
else if (cnode is XmlElement)
StoreChildNode(childNodeNames, cnode.Name, cnode);
}
// Now output all stored info
foreach (string childname in childNodeNames.Keys)
{
List<object> alChild = (List<object>)childNodeNames[childname];
if (alChild.Count == 1)
OutputNode(childname, alChild[0], sbJSON, true);
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
foreach (object Child in alChild)
OutputNode(childname, Child, sbJSON, false);
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" ], ");
}
}
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" }");
}
// StoreChildNode: Store data associated with each nodeName
// so that we know whether the nodeName is an array or not.
private static void StoreChildNode(SortedList<string, object> childNodeNames, string nodeName, object nodeValue)
{
// Pre-process contraction of XmlElement-s
if (nodeValue is XmlElement)
{
// Convert <aa></aa> into "aa":null
// <aa>xx</aa> into "aa":"xx"
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] is XmlText))
nodeValue = ((XmlText)(children[0])).InnerText;
}
}
// Add nodeValue to ArrayList associated with each nodeName
// If nodeName doesn't exist then add it
List<object> ValuesAL;
if (childNodeNames.ContainsKey(nodeName))
{
ValuesAL = (List<object>)childNodeNames[nodeName];
}
else
{
ValuesAL = new List<object>();
childNodeNames[nodeName] = ValuesAL;
}
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("null");
}
else if (alChild is string)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
string sChild = (string)alChild;
sChild = sChild.Trim();
sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
}
else
XmlToJSONnode(sbJSON, (XmlElement)alChild, showNodeName);
sbJSON.Append(", ");
}
// Make a string safe for JSON
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();
}
}
string xml = "<menu id=\"file\" value=\"File\"> " +
"<popup>" +
"<menuitem value=\"New\" onclick=\"CreateNewDoc()\" />" +
"<menuitem value=\"Open\" onclick=\"OpenDoc()\" />" +
"<menuitem value=\"Close\" onclick=\"CloseDoc()\" />" +
"</popup>" +
"</menu>";
string json = JSON.XmlToJSON(xml);
// json = { "menu": {"id": "file", "popup": { "menuitem": [ {"onclick": "CreateNewDoc()", "value": "New" }, {"onclick": "OpenDoc()", "value": "Open" }, {"onclick": "CloseDoc()", "value": "Close" } ] }, "value": "File" }}
试试这个函数。我刚写完它,还没有多少机会测试,但我的初步测试很有前途。
public static XmlDocument JsonToXml(string json)
{
XmlNode newNode = null;
XmlNode appendToNode = null;
XmlDocument returnXmlDoc = new XmlDocument();
returnXmlDoc.LoadXml("<Document />");
XmlNode rootNode = returnXmlDoc.SelectSingleNode("Document");
appendToNode = rootNode;
string[] arrElementData;
string[] arrElements = json.Split('\r');
foreach (string element in arrElements)
{
string processElement = element.Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim();
if ((processElement.IndexOf("}") > -1 || processElement.IndexOf("]") > -1) && appendToNode != rootNode)
{
appendToNode = appendToNode.ParentNode;
}
else if (processElement.IndexOf("[") > -1)
{
processElement = processElement.Replace(":", "").Replace("[", "").Replace("\"", "").Trim();
newNode = returnXmlDoc.CreateElement(processElement);
appendToNode.AppendChild(newNode);
appendToNode = newNode;
}
else if (processElement.IndexOf("{") > -1 && processElement.IndexOf(":") > -1)
{
processElement = processElement.Replace(":", "").Replace("{", "").Replace("\"", "").Trim();
newNode = returnXmlDoc.CreateElement(processElement);
appendToNode.AppendChild(newNode);
appendToNode = newNode;
}
else
{
if (processElement.IndexOf(":") > -1)
{
arrElementData = processElement.Replace(": \"", ":").Replace("\",", "").Replace("\"", "").Split(':');
newNode = returnXmlDoc.CreateElement(arrElementData[0]);
for (int i = 1; i < arrElementData.Length; i++)
{
newNode.InnerText += arrElementData[i];
}
appendToNode.AppendChild(newNode);
}
}
}
return returnXmlDoc;
}
JSON
字符串转换为 XML
,可以尝试以下方法: public string JsonToXML(string json)
{
XDocument xmlDoc = new XDocument(new XDeclaration("1.0", "utf-8", ""));
XElement root = new XElement("Root");
root.Name = "Result";
var dataTable = JsonConvert.DeserializeObject<DataTable>(json);
root.Add(
from row in dataTable.AsEnumerable()
select new XElement("Record",
from column in dataTable.Columns.Cast<DataColumn>()
select new XElement(column.ColumnName, row[column])
)
);
xmlDoc.Add(root);
return xmlDoc.ToString();
}
如果需要将 XML
转换为 JSON
,可以尝试以下方法:
public string XmlToJson(string xml)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
return jsonText;
}
DeserializeXNode
且代码形式为XNode node = JsonConvert.DeserializeXNode(json, "Root")
,因为在另一个中你使用了SerializeXmlNode
吗? - Vinod Srivastav这里有一个简单的代码片段,可以将XmlNode(递归地)转换成哈希表,并将多个相同子项组合成数组(ArrayList)。 大多数JSON库通常接受哈希表作为JSON的转换格式。
protected object convert(XmlNode root){
Hashtable obj = new Hashtable();
for(int i=0,n=root.ChildNodes.Count;i<n;i++){
object result = null;
XmlNode current = root.ChildNodes.Item(i);
if(current.NodeType != XmlNodeType.Text)
result = convert(current);
else{
int resultInt;
double resultFloat;
bool resultBoolean;
if(Int32.TryParse(current.Value, out resultInt)) return resultInt;
if(Double.TryParse(current.Value, out resultFloat)) return resultFloat;
if(Boolean.TryParse(current.Value, out resultBoolean)) return resultBoolean;
return current.Value;
}
if(obj[current.Name] == null)
obj[current.Name] = result;
else if(obj[current.Name].GetType().Equals(typeof(ArrayList)))
((ArrayList)obj[current.Name]).Add(result);
else{
ArrayList collision = new ArrayList();
collision.Add(obj[current.Name]);
collision.Add(result);
obj[current.Name] = collision;
}
}
return obj;
}
JSON转换为Xml
,网址为https://www.newtonsoft.com/json/help/html/ConvertJsonToXml.htm,将`Xml转换为JSON`,网址为https://www.newtonsoft.com/json/help/html/ConvertXmlToJson.htm。 - Vinod Srivastav