programing

JSON을 XML로 변환하거나 XML을 JSON으로 변환하는 방법

starjava 2023. 3. 18. 08:13
반응형

JSON을 XML로 변환하거나 XML을 JSON으로 변환하는 방법

나는 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과 XML을 JSON으로 변환합니다.네트워크

네, 그렇게 할 수 있지만 변환할 때 몇 가지 모순을 인식하고 적절하게 대처하십시오.모든 인터페이스의 가능성에 자동적으로 준거할 수는 없습니다.또한 변환 제어에 대한 지원도 한정되어 있습니다.많은 JSON 구조와 값은 양방향으로 자동 변환할 수 없습니다.마일리지가 달라질 수 있도록 Newtonsoft JSON 라이브러리와 MS XML 라이브러리에서 기본 설정을 사용하고 있습니다.

XML -> JSON

  1. 모든 데이터는 문자열 데이터가 됩니다(를 들어 항상 false가 아닌 "false" 또는 "0"이 아닌 "0"이 됩니다). JavaScript는 이러한 데이터를 특정 상황에서 다르게 처리합니다.
  2. 가 될 수 .{} OR " " "[ {} {} ...]XML 자 요소가 하나 이상인지에 따라 달라집니다.JavaScript 등에서는 이 두 가지를 다르게 사용할 수 있습니다.같은 스키마에 준거한 XML의 예에 따라 실제로 다른 JSON 구조가 생성될 수 있습니다.json 속성을 추가할 수 있습니다.일부(전부는 아님)의 경우 문제를 해결하려면 Array='true'를 사용합니다.
  3. XML은 매우 적절한 형식이어야 합니다.W3C 표준에 완전히 준거할 필요는 없지만 1.루트 요소가 있어야 합니다.2 . 요소 이름을 숫자로 시작할 수 없습니다는 Newtonsoft 및 MS 라이브러리를 사용할 때 확인한 두 가지 강제 XML 표준입니다.
  4. 이전 버전에서는 블랭크 요소가 JSON으로 변환되지 않습니다.무시당합니다.공백 요소는 "element"가 되지 않습니다.null

새로운 업데이트로 늘 처리 방법이 변경되었습니다(Jon Story가 지적해 주셔서 감사합니다). https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm

JSON -> XML

  1. 루트 XML 요소로 변환할 최상위 개체가 필요합니다. 그렇지 않으면 파서가 실패합니다.
  2. 오브젝트명은 요소로 변환할 수 없기 때문에 숫자로 시작할 수 없습니다(XML은 기술적으로 이보다 더 엄격합니다). 그러나 다른 요소 이름 지정 규칙 중 일부를 어길 수는 있습니다.

그 밖에 다른 문제가 있으면 언제든지 말씀해 주십시오.저는 현을 준비하고 청소하는 커스텀 루틴을 개발했습니다.상황에 따라 준비/정리가 필요할 수도 있고 그렇지 않을 수도 있습니다.StaxMan이 언급한 바와 같이 실제로 객체 간에 변환이 필요할 수 있습니다.여기에는 적절한 인터페이스와 상기의 경고에 대처하기 위한 다수의 케이스 스테이트먼트 등이 수반될 가능성이 있습니다.

이러한 변환은, 에서도 실행할 수 있습니다.NET 프레임워크:

JSON에서 XML: 시스템을 사용합니다.런타임시리얼화제이슨

var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
    Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));

XML에서 JSON으로: 시스템 사용.Web.스크립트시리얼화

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에서는 변환 메서드는 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);

외부 어셈블리/프로젝트를 사용하지 않기 위해 수용된 솔루션에 대한 대체 코드를 찾기 위해 오랫동안 찾아다녔습니다.Dynamic Json 프로젝트의 소스 코드 덕분에 다음과 같은 생각을 하게 되었습니다.

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 용도의 XElement가 아닌 Xml Document를 원했습니다.또, 이 코드는 분명히 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" }}

「」의 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;
     }

다음은 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;
}

이 기능을 사용해 보세요.그냥 쓰고 시험해 볼 기회가 별로 없었지만, 예비시험은 유망해요.

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

나는 데이비드 브라운이 말한 대로 했지만 다음과 같은 예외가 있었다.

$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>

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

Item이라는 클래스를 사용하여 요소를 표현했습니다.

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

동작하고 있습니다.

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

바이올린 샘플: https://dotnetfiddle.net/enUJKu

기타 도움말에 대해서는 Code Project 문서를 참조하십시오.

면책사항:제가 이 도서관의 저자입니다.

다음으로 를 사용하여 JSON을 XML로 변환하는 예를 나타냅니다.NET 내장 라이브러리(Newtonsoft와 같은 서드파티 라이브러리 대신).

using System.Text.Json;
using System.Text.Json.Nodes;
using System.Xml.Linq;

XDocument xmlDoc = jsonToXml(jsonObj);

private XDocument jsonToXml(JsonObject obj)
{
  var xmlDoc = new XDocument();
  var root = new XElement("Root");
  xmlDoc.Add(root);

  foreach (var prop in obj)
  {
    var xElement = new XElement(prop.Key);
    xElement.Value = prop.Value.ToString();
    root.Add(xElement);
  }
  return xmlDoc;
}

언급URL : https://stackoverflow.com/questions/814001/how-to-convert-json-to-xml-or-xml-to-json

반응형