JSON biçiminde bir dizeyi nesneye veya viceversa'ya dönüştürmek için Json.NET kullanmaya başladım. Json.NET çerçevesinde emin değilim, JSON bir dize XML formatı ve viceversa dönüştürmek mümkün mü?
JSON biçiminde bir dizeyi nesneye veya viceversa'ya dönüştürmek için Json.NET kullanmaya başladım. Json.NET çerçevesinde emin değilim, JSON bir dize XML formatı ve viceversa dönüştürmek mümkün mü?
Yanıtlar:
Evet. Bu kesin amaç için yardımcı yöntemler içeren JsonConvert sınıfını kullanarak:
// 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);
Buradaki belgeler: Json.NET ile JSON ve XML arasında dönüştürme
Evet, yapabilirsin (yaparım) ama dönüştürürken bazı paradoksların farkında ol ve uygun şekilde idare et. Tüm arayüz olasılıklarına otomatik olarak uyum sağlayamazsınız ve dönüşümü kontrol etmede sınırlı yerleşik destek vardır - birçok JSON yapısı ve değeri otomatik olarak her iki yöne dönüştürülemez. Unutmayın, Newtonsoft JSON kütüphanesi ve MS XML kütüphanesi ile varsayılan ayarları kullanıyorum, böylece kilometreniz değişebilir:
{}
VEYA iç içe dizi [ {} {} ...]
olabilir. Bunları JavaScript, vb. İle farklı şekilde tüketirsiniz. Aynı şemaya uyan farklı XML örnekleri aslında bu şekilde farklı JSON yapıları üretebilir. Bazı (ancak mutlaka hepsi değil) durumlarda bu sorunu çözmek için öğenize json: Array = 'true' özelliğini ekleyebilirsiniz .Yeni bir güncelleme bunu değiştirdi (Jon Story'ye işaret ettiği için teşekkürler): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
Lütfen fark ettiğiniz diğer sorunlardan bahsetmekten çekinmeyin, ileri geri dönüştürürken dizeleri hazırlamak ve temizlemek için kendi özel rutinlerimi geliştirdim. Durumunuz hazırlık / temizlik gerektirebilir veya etmeyebilir. StaxMan'ın belirttiği gibi, durumunuz aslında nesneler arasında dönüşüm yapmanızı gerektirebilir ...
Bu dönüşümleri .NET Framework ile de yapabilirsiniz:
JSON'dan XML'e: System.Runtime.Serialization.Json kullanarak
var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));
XML'den JSON'a: System.Web.Script.Serialization kullanarak
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 } };
}
Böyle bir dönüşümde nokta olduğundan emin değilim (evet, birçok yap, ama çoğunlukla yuvarlak delikten kare bir peg zorlamak için) - yapısal empedans uyuşmazlığı var ve dönüşüm kayıplı. Bu yüzden bu formattan formata dönüşümlere karşı öneriyorum.
Ancak bunu yaparsanız, önce json'dan nesneye, sonra nesneden xml'ye (ve tersine tersi) dönüştürün. Doğrudan dönüşüm yapmak çirkin bir çıktıya, bilgi kaybına veya muhtemelen her ikisine de yol açar.
David Brown'un cevabı için teşekkürler . Benim durumumda JSON.Net 3.5, dönüştürme yöntemleri JsonConvert statik sınıf altında:
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);
Dış montaj / proje kullanmama umuduyla kabul edilen çözümün alternatif kodunu bulmak için uzun süre aradım. DynamicJson projesinin kaynak kodu sayesinde aşağıdakileri buldum :
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;
}
Not: xPath amaçları için bir XElement yerine bir XmlDocument istedim. Ayrıca, bu kod açıkça sadece JSON'dan XML'e gider, tersini yapmanın çeşitli yolları vardır.
İşte xml'yi json'a dönüştürmek için tam c # kodu
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();
}
}
Belirli bir XML dizesini JSON'a dönüştürmek için aşağıdaki gibi XmlToJSON () işlevini çağırmanız yeterlidir.
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" }}
Bu işlevi deneyin. Sadece yazdım ve test etme şansım olmadı, ancak ön testlerim umut vericidir.
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;
}
Burada, bir XmlNode'u (özyinelemeli olarak) karma bir biçime dönüştüren ve aynı alt öğenin birden çok örneğini (ArrayList olarak) bir diziye gruplayan basit bir snippet vardır. Hashtable genellikle JSON kitaplıklarının çoğu tarafından JSON'a dönüştürülür.
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;
}
Cinchoo ETL - Xml'in JSON'a birkaç kod satırı ile kolayca dönüştürülebilmesi için açık kaynaklı bir kütüphane
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);
}
}
Ek yardım için Checkout CodeProject makalesi.
Feragatname: Bu kütüphanenin yazarıyım.
David Brown'un dediği gibi yaptım ama şu istisnayı yaşadım.
$exception {"There are multiple root elements. Line , position ."} System.Xml.XmlException
Bir çözüm, XML dosyasını bir kök öğeyle değiştirmek olabilir, ancak bu her zaman gerekli değildir ve bir XML akışı için de mümkün olmayabilir. Benim çözüm aşağıda:
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);
}
}
}
}
Hatayı oluşturan örnek XML:
<parent>
<child>
Text
</child>
</parent>
<parent>
<child>
<grandchild>
Text
</grandchild>
<grandchild>
Text
</grandchild>
</child>
<child>
Text
</child>
</parent>
JSON XML dönüştürmek için aşağıdaki yöntemleri kullandım
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();
}
}
Ve
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();
}
Öğeleri temsil etmek için Öğe adlı sınıfı kullandım
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; }
}
İşe yarıyor....
Dönüştürme JSON
dizesi için şunu XML
deneyin:
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();
}
Dönüştürmek XML
için şunu JSON
deneyin:
public string XmlToJson(string xml)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
return jsonText;
}
JSON veya XML Dizesini ayrıştırmak için kendi kodunu yazmak yerine üçüncü taraf kitaplığını kullanın. Bir kez kullanılıyorsa, çevrimiçi dönüştürmeyi deneyin. Json'dan Xml'ye https://www.easycodeforall.com/Json2Xml.jsp Xml'den Json'a https://www.easycodeforall.com/Xml2Json.jsp