Ich fing an, Json.NET zu verwenden, um einen String im JSON-Format in object oder viceversa zu konvertieren. Ich bin mir nicht sicher, ob es im Json.NET-Framework möglich ist, eine Zeichenfolge in JSON in das XML-Format und umgekehrt zu konvertieren.
Ja. Verwenden Sie für diesen genauen Zweck die JsonConvert-Klasse, die Hilfsmethoden enthält:
// 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);
Dokumentation hier: Konvertierung zwischen JSON und XML mit Json.NET
Ja, Sie können es tun (ich tue es), aber seien Sie sich einiger Paradoxe bewusst, wenn Sie konvertieren, und gehen Sie angemessen damit um. Sie können nicht alle Schnittstellenmöglichkeiten automatisch anpassen, und die integrierte Unterstützung für die Steuerung der Konvertierung ist begrenzt. Viele JSON-Strukturen und -Werte können nicht automatisch in beide Richtungen konvertiert werden. Beachten Sie, dass ich die Standardeinstellungen für die Newtonsoft JSON-Bibliothek und die MS XML-Bibliothek verwende, sodass Ihre Laufleistung variieren kann:
{}
_ OR verschachtelten Arrays _[ {} {} ...]
_ werden, je nachdem, ob es nur ein oder mehrere untergeordnete XML-Elemente gibt. Sie würden diese beiden in JavaScript usw. unterschiedlich verwenden. Verschiedene XML-Beispiele, die demselben Schema entsprechen, können auf diese Weise tatsächlich unterschiedliche JSON-Strukturen erzeugen. Sie können das Attribut json: Array = 'true' zu Ihrem Element hinzufügen, um dies in einigen Fällen zu umgehen (aber nicht unbedingt alle) Fälle.Ein neues Update ändert dies (Dank an Jon Story für den Hinweis): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
Bitte zögern Sie nicht, andere Probleme zu erwähnen, die Sie bemerkt haben. Ich habe meine eigenen benutzerdefinierten Routinen zum Vorbereiten und Reinigen der Zeichenfolgen beim Konvertieren hin und her entwickelt. Ihre Situation erfordert möglicherweise Vorbereitungen/Aufräumarbeiten. Wie StaxMan erwähnt, kann es in Ihrer Situation tatsächlich erforderlich sein, dass Sie zwischen Objekten konvertieren. Dies kann geeignete Schnittstellen und eine Reihe von case-Anweisungen/etc zur Folge haben, um die oben erwähnten Vorbehalte zu beseitigen.
Sie können diese Konvertierungen auch mit .NET Framework durchführen:
JSON nach XML: mit System.Runtime.Serialization.Json
var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));
XML zu JSON: mithilfe von 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 } };
}
Danke für die Antwort von David Brown. In meinem Fall von JSON.Net 3.5 befinden sich die Konvertierungsmethoden unter der statischen Klasse von 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);
Ich bin mir nicht sicher, ob es bei einer solchen Umwandlung einen Punkt gibt (ja, viele tun es, aber meistens, um einen quadratischen Stift durch ein rundes Loch zu zwingen) - es gibt eine strukturelle Impedanzinkongruenz und die Umwandlung ist verlustbehaftet. Ich würde also gegen solche Format-zu-Format-Transformationen empfehlen.
Wenn Sie dies tun, konvertieren Sie zuerst von Json zu Objekt, dann von Objekt in XML (und umgekehrt für die umgekehrte Richtung). Direkte Transformation führt zu hässlicher Ausgabe, Informationsverlust oder möglicherweise zu beidem.
Ich habe lange gesucht, um alternativen Code für die akzeptierte Lösung zu finden, in der Hoffnung, keine externen Assemblys/Projekte zu verwenden. Dank des Quellcodes des DynamicJson -Projekts habe ich Folgendes gefunden:
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;
}
Hinweis: Ich wollte für XPath-Zwecke ein XmlDocument-Objekt anstelle eines XElement-Dokuments .. Dieser Code geht natürlich nur von JSON zu XML.
Hier ist der vollständige C # -Code zum Konvertieren von XML in 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();
}
}
Um eine bestimmte XML-Zeichenfolge in JSON zu konvertieren, rufen Sie einfach die XmlToJSON () - Funktion wie folgt auf.
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" }}
Versuchen Sie diese Funktion. Ich habe es gerade geschrieben und hatte keine große Chance, es zu testen, aber meine vorläufigen Tests sind vielversprechend.
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;
}
Hier ist ein einfacher Ausschnitt, der einen XmlNode (rekursiv) in eine Hashtabelle konvertiert und mehrere Instanzen desselben untergeordneten Objekts in einem Array (als ArrayList) gruppiert. Die Hashtable wird normalerweise von den meisten JSONs in JSON konvertiert Bibliotheken.
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;
}
Um JSON
in XML
zu konvertieren, versuchen Sie Folgendes:
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();
}
Zum Konvertieren von XML
in JSON
versuchen Sie Folgendes:
public string XmlToJson(string xml)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
return jsonText;
}
Ich habe es wie David Brown gesagt, aber ich bekam die folgende Ausnahme.
$exception {"There are multiple root elements. Line , position ."} System.Xml.XmlException
Eine Lösung wäre, die XML-Datei mit einem Root-Element zu ändern. Dies ist jedoch nicht immer erforderlich und für einen XML-Stream möglicherweise auch nicht möglich. Meine Lösung unten:
var path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\App_Data"));
var directoryInfo = new DirectoryInfo(path);
var fileInfos = directoryInfo.GetFiles("*.xml");
foreach (var fileInfo in fileInfos)
{
XmlDocument doc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create(fileInfo.FullName, settings))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
var node = doc.ReadNode(reader);
string json = JsonConvert.SerializeXmlNode(node);
}
}
}
}
Beispiel-XML, das den Fehler generiert:
<parent>
<child>
Text
</child>
</parent>
<parent>
<child>
<grandchild>
Text
</grandchild>
<grandchild>
Text
</grandchild>
</child>
<child>
Text
</child>
</parent>
Cinchoo ETL - eine Open-Source-Bibliothek, die für die einfache Konvertierung von XML in JSON mit wenigen Codezeilen verfügbar ist
Xml -> JSON:
using (var p = new ChoXmlReader("sample.xml"))
{
using (var w = new ChoJSONWriter("sample.json"))
{
w.Write(p);
}
}
JSON -> Xml:
using (var p = new ChoJsonReader("sample.json"))
{
using (var w = new ChoXmlWriter("sample.xml"))
{
w.Write(p);
}
}
Checkout CodeProject-Artikel für zusätzliche Hilfe.
Haftungsausschluss: Ich bin der Autor dieser Bibliothek.
Ich habe die folgenden Methoden verwendet, um JSON in XML zu konvertieren
List<Item> items;
public void LoadJsonAndReadToXML()
{
using (StreamReader r = new StreamReader(@"E:\Json\overiddenhotelranks.json"))
{
string json = r.ReadToEnd();
items = JsonConvert.DeserializeObject<List<Item>>(json);
ReadToXML();
}
}
und
public void ReadToXML()
{
try
{
var xEle = new XElement("Items",
from item in items
select new XElement("Item",
new XElement("mhid", item.mhid),
new XElement("hotelName", item.hotelName),
new XElement("destination", item.destination),
new XElement("destinationID", item.destinationID),
new XElement("rank", item.rank),
new XElement("toDisplayOnFod", item.toDisplayOnFod),
new XElement("comment", item.comment),
new XElement("Destinationcode", item.Destinationcode),
new XElement("LoadDate", item.LoadDate)
));
xEle.Save("E:\\employees.xml");
Console.WriteLine("Converted to XML");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
Ich habe die Klasse mit dem Namen Item verwendet, um die Elemente darzustellen
public class Item
{
public int mhid { get; set; }
public string hotelName { get; set; }
public string destination { get; set; }
public int destinationID { get; set; }
public int rank { get; set; }
public int toDisplayOnFod { get; set; }
public string comment { get; set; }
public string Destinationcode { get; set; }
public string LoadDate { get; set; }
}
Es klappt....