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-> JSON
- 모든 데이터는 (예를 들어, 당신은 항상 얻을 것이다 문자열 데이터가된다 “false”를 하지 거짓 또는 “0” 하지 0 분명히 자바 스크립트는 어떤 경우에 다르게이 취급).
- 하위 요소는 둘 이상의 XML 하위 요소가 있는지 여부에 따라
{}
중첩 오브젝트 또는 중첩 배열 이 될 수 있습니다[ {} {} ...]
. JavaScript 등에서이 두 가지를 다르게 사용할 것입니다. 동일한 스키마를 따르는 XML의 다른 예제는 실제로 이런 방식으로 다른 JSON 구조를 생성 할 수 있습니다. json : Array = ‘true’ 속성을 요소에 추가하여 일부 (전부는 아님) 경우에이 문제를 해결할 수 있습니다. - 귀하의 XML은 상당히 잘 구성되어 있어야하며 W3C 표준을 완벽하게 준수 할 필요는 없지만 1. 루트 요소가 있어야하며 2. 숫자로 요소 이름을 시작할 수 없습니다. 강제 XML 표준 중 두 가지입니다. Newtonsoft 및 MS 라이브러리를 사용할 때 발견했습니다.
- 이전 버전에서는 Blank 요소가 JSON으로 변환되지 않습니다. 그들은 무시됩니다. 빈 요소는 “요소” 가되지 않습니다 .
새로운 업데이트로 변경되었습니다 (Jon Story에게 알려 주셔서 감사합니다) : https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
JSON-> XML
- 루트 XML 요소로 변환 할 최상위 레벨 오브젝트가 필요하거나 구문 분석기가 실패합니다.
- 객체 이름은 요소로 변환 할 수 없으므로 숫자로 시작할 수 없지만 (XML은 기술적으로 이보다 훨씬 엄격합니다.) 다른 요소 명명 규칙을 위반하면 ‘피할 수 있습니다’.
당신이 알아 차린 다른 문제들에 대해 언급 해 주시기 바랍니다. 나는 앞뒤로 변환 할 때 줄을 준비하고 청소하기위한 나만의 맞춤형 루틴을 개발했습니다. 귀하의 상황은 준비 / 정리를 요구하거나 요구하지 않을 수 있습니다. StaxMan이 언급했듯이, 실제로 상황에 따라 객체를 변환해야 할 수도 있습니다 … 이것은 위에서 언급 한주의 사항을 처리하기 위해 적절한 인터페이스와 많은 사례 진술 등을 수반 할 수 있습니다.
답변
.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에서 객체로 변환 한 다음 객체에서 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 목적으로 XElement가 아닌 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" }}