문제

JSON.NET을 사용하여 JSON 형식의 문자열을 Object 또는 Vice로 변환하기 시작했습니다. JSON.NET 프레임 워크에서는 확실하지 않습니다.

도움이 되었습니까?

해결책

예. 이 정확한 목적을위한 도우미 방법이 포함 된 JSONCONTTER 클래스 사용 :

// 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과 XML을 JSON.NET으로 변환합니다

다른 팁

그래요 당신 ~할 수 있다 그것을 (나는), 그러나 전환 할 때 몇 가지 역설을 알고 적절하게 처리하십시오. 모든 인터페이스 가능성을 자동으로 준수 할 수 없으며 변환 제어에 대한 내장 지원이 제한되어 있습니다. 많은 JSON 구조와 값이 두 가지 방법으로 자동 변환 될 수 없습니다. NewTonsoft JSON 라이브러리 및 MS XML 라이브러리와 함께 기본 설정을 사용하고 있으므로 마일리지가 다를 수 있습니다.

XML-> JSON

  1. 모든 데이터는 문자열 데이터가됩니다 (예 : 항상 얻을 수 있습니다. "거짓" ~ 아니다 거짓 또는 "0" ~ 아니다 0) 분명히 JavaScript는 특정한 경우에 다르게 취급합니다.
  2. 어린이 요소는 중첩성이 될 수 있습니다 {} 또는 중첩 배열 [ {} {} ...] 하나 이상의 XML 하위 요소 만있는 경우에 따라 이 두 가지를 JavaScript 등에서 다르게 소비합니다. 동일한 스키마를 준수하는 XML의 다른 예는 실제로 다른 JSON 구조를 생성 할 수 있습니다. 속성을 추가 할 수 있습니다 JSON : Array = 'true' 당신의 요소는 이것을 해결하기 위해 이것을 해결합니다.
  3. XML이어야합니다 잘 알고있는 나는 W3C 표준을 완벽하게 준수 할 필요가 없지만 1. 루트 요소와 2가 있어야한다는 것을 알았습니다. 숫자로 요소 이름을 시작할 수는 없습니다. NewTonsoft 및 MS 라이브러리.
  4. 이전 버전에서는 빈 요소가 JSON으로 변환되지 않습니다. 그들은 무시됩니다. 빈 요소가되지 않습니다 "요소": NULL

새로운 업데이트는 이것을 변경합니다 (Jon Story 덕분에 그것을 지적했습니다) : https://www.newtonsoft.com/json/help/html/t_newtonsoft_json_nullvaluehandling.htm

JSON-> XML

  1. 루트 XML 요소로 변환되는 최상위 객체가 필요하거나 구문 분석기가 실패합니다.
  2. 요소로 변환 할 수 없으므로 객체 이름은 숫자로 시작할 수 없지만 (XML은 기술적 으로이보다 훨씬 엄격합니다) 다른 요소 이름 지정 규칙을 깨뜨릴 수있는 '도망 갈 수 있습니다'.

당신이 알아 차린 다른 문제를 자유롭게 언급하십시오, 나는 앞뒤로 변환 할 때 문자열을 준비하고 청소하기위한 내 자신의 맞춤형 루틴을 개발했습니다. 귀하의 상황은 준비/청소를 요청하거나 요구하지 않을 수 있습니다. Staxman이 언급 한 바와 같이, 귀하의 상황에서는 실제로 객체를 변환해야 할 수도 있습니다. 이는 위에서 언급 한 경고를 처리하기 위해 적절한 인터페이스와 많은 사례 문을 수반 할 수 있습니다.

.NET 프레임 워크를 사용하여 이러한 변환을 수행 할 수 있습니다.

json to 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에서 객체로 변환 한 다음 객체에서 XML로 변환하십시오 (반대 방향의 경우 그 반대). 직접 변환을 수행하면 추악한 출력, 정보 손실 또는 둘 다가됩니다.

David Brown의 답변에 감사드립니다. JSON.NET 3.5의 경우 변환 메소드는 JSONCONTTER STATIC 클래스 아래에 있습니다.

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 목적으로 Xlement가 아닌 XMLDocument를 원했습니다. 또한이 코드는 분명히 JSON에서 XML로만 이동하므로 반대를 수행하는 다양한 방법이 있습니다.

다음은 XML을 JSON으로 변환하는 전체 C# 코드입니다.

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();
 }
}

주어진 XML 문자열을 JSON으로 변환하려면 아래와 같이 xmltojson () 함수를 호출하십시오.

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;
}

다음은 xmlnode (재귀 적으로)를 해시 가능으로 변환하는 간단한 스 니펫이며, 동일한 자식의 여러 인스턴스를 배열 (배열 목록)으로 그룹화합니다. 해시 테이블은 일반적으로 대부분의 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;
}

나는 David Brown이 말한 것을 좋아했지만 다음과 같은 예외를 얻었습니다.

$exception {"There are multiple root elements. Line , position ."} System.Xml.XmlException

한 가지 솔루션은 루트 요소로 XML 파일을 수정하는 것입니다. 그러나 항상 필요한 것은 아니며 XML 스트림의 경우 불가능할 수도 있습니다. 아래의 내 솔루션 :

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);
            }
        }
    }
}

오류를 생성하는 예제 XML :

<parent>
    <child>
        Text
    </child>
</parent>
<parent>
    <child>
        <grandchild>
            Text
        </grandchild>
        <grandchild>
            Text
        </grandchild>
    </child>
    <child>
        Text
    </child>
</parent>

CINCHOO ETL - 몇 줄의 코드로 XML을 JSON으로 쉽게 변환 할 수있는 오픈 소스 라이브러리

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);
    }
}

추가 도움을 받으려면 CodeProject 기사를 확인하십시오.

면책 조항 : 저는이 도서관의 저자입니다.

아래 방법을 사용하여 JSON을 XML로 변환했습니다.

        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();
            }
        }

그리고

        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();
        }

나는 이름이 지정된 항목을 사용하여 요소를 나타냅니다.

    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; }

    }

효과가있다....

변환을 위해 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;
     }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top