Я начал использовать Json.NET для преобразования строки в формате JSON в объект или наоборот. Я не уверен в структуре Json.NET, возможно ли преобразовать строку в формате JSON в формат XML и наоборот?
Обратите внимание, как сказал StaxMan, если есть бывший. пространство в узле элемента, оно будет проигнорировано xml. Например «Student Id»: 11000 не будет в xml результате bcuz пробела в имени свойства. XML не допускает наличие пробела в элементном узле.
Даниэль Б,
Ответы:
424
Да. Используя класс JsonConvert, который содержит вспомогательные методы для этой конкретной цели:
// To convert an XML node contained in string xml into a JSON string XmlDocument doc =newXmlDocument();
doc.LoadXml(xml);string jsonText =JsonConvert.SerializeXmlNode(doc);// To convert JSON text contained in string json into an XML nodeXmlDocument doc =JsonConvert.DeserializeXmlNode(json);
Просто к вашему сведению, здесь есть потенциальная проблема. Когда я превращал массив узлов xml в json, он создавал массив в json. Но когда я запускаю массив узлов xml с числом 1, преобразование json больше не форматирует массив. Здесь массив XML с одним элементом теряется при переводе.
Левитикон
3
Сюрприз-сюрприз - это импеданс между XML и JSON и причина, по которой (IMO) не очень хорошая идея для прямого преобразования между ними. Но, эй, есть много разработчиков, которые категорически не согласны (в соответствии с отрицательными отзывами в моем ответе) и не возражают против этих случайных преобразований данных или потенциальной потери данных ...
StaxMan
7
@StaxMan: Я думаю, что все могут согласиться с тем, что не существует стандартного способа представления XML-документа в формате JSON. Ваш ответ, вероятно, был отвергнут, потому что он на самом деле не ответил на вопрос. ОП не спрашивал, должен ли он сделать преобразование, а скорее мог ли он сделать это, используя инструменты, уже имеющиеся в его распоряжении.
Дэвид Браун
46
Да, вы можете сделать это (я делаю), но помните о некоторых парадоксах при конвертации и действуйте соответствующим образом. Вы не можете автоматически соответствовать всем возможностям интерфейса, и имеется ограниченная встроенная поддержка в управлении преобразованием - многие структуры и значения JSON не могут автоматически преобразовываться в обоих направлениях. Помните, что я использую настройки по умолчанию с библиотекой Newtonsoft JSON и библиотекой MS XML, поэтому ваш пробег может варьироваться:
XML -> JSON
Все данные становятся строковыми данными (например, вы всегда получите «ложь», а не ложь или «0», а не 0 ). Очевидно, что в некоторых случаях JavaScript обрабатывает их по-разному.
Дочерние элементы могут стать вложенным объектом {}или вложенным массивом в [ {} {} ...]зависимости от того, есть ли один или несколько дочерних элементов XML. Вы бы по-разному использовали эти два в JavaScript и т. Д. Различные примеры XML, соответствующего одной и той же схеме, могут таким образом создавать действительно разные структуры JSON. Вы можете добавить атрибут json: Array = 'true' к своему элементу, чтобы обойти это в некоторых (но не обязательно во всех) случаях.
Ваш XML должен быть достаточно хорошо сформирован, я заметил, что он не обязательно должен полностью соответствовать стандарту W3C, но 1. у вас должен быть корневой элемент и 2. вы не можете начинать имена элементов с чисел - это два из обязательных стандартов XML Я нашел при использовании библиотек Newtonsoft и MS.
В старых версиях пустые элементы не преобразуются в JSON. Они игнорируются. Пустой элемент не становится "элементом": null
Вам нужен объект верхнего уровня, который преобразуется в корневой элемент XML, иначе парсер не удастся.
Имена ваших объектов не могут начинаться с цифры, поскольку они не могут быть преобразованы в элементы (XML технически даже более строг, чем этот), но я могу «сойти» с нарушением некоторых других правил именования элементов.
Пожалуйста, не стесняйтесь упоминать о любых других проблемах, которые вы заметили, я разработал свои собственные пользовательские процедуры для подготовки и очистки строк, когда я конвертирую туда-сюда. Ваша ситуация может требовать или не требовать подготовки / очистки. Как упоминает StaxMan, в вашей ситуации может потребоваться преобразование между объектами ... это может повлечь за собой соответствующие интерфейсы и кучу операторов case / etc для обработки предостережений, которые я упомянул выше.
Это! Хорошая проработка того, на чем был основан мой короткий (и в какой-то момент сильно опущенный) ответ - есть много-много подводных камней, если вы делаете слепое прямое обращение. Они могут не блокировать проблемы для конкретного использования, но также могут быть очень неприятными для других.
StaxMan
1
Что касается # 4 в XML -> JSON: вы можете использовать свойство NullValueHandling, чтобы указать, что нулевые значения должны быть включены явно - newtonsoft.com/json/help/html/…
Jon Story
Описание проблемы в этом комментарии применимо ко ВСЕМ реализациям алгоритмов, которые преобразуют JSON в XML или наоборот. Как только человек признает, что невозможно одновременно достичь идеальной двунаправленной верности и в то же время вводить и выводить «партийные» или «ограниченные» эфиры («предопределенная схема / формат»). - в общем случае.
ДАЛЬДЕЙ
33
Вы можете сделать эти преобразования также с .NET Framework:
Я получаю сообщение об ошибке GetXmlData «Имя GetXmlData не существует в текущем контексте». Есть ли какая-либо директива using, которую я пропускаю?
TimSmith-Aardwolf
4
@ TimSmith-Aardwolf, вот весь код, который тебе нужен. Для использования System.Web.Script.Serialization необходимо добавить сборку System.Web.Extensions в списке литературы.
Термининя
@Termininja, JSON to XML также дает мне тип, как это убрать?
взломщик
@Termininja, отлично, спасибо.
взломщик
30
Я не уверен, что в таком преобразовании есть смысл (да, многие это делают, но в основном для принудительного подвода квадратного колышка через круглое отверстие) - структурное несоответствие импеданса и преобразование с потерями. Поэтому я бы рекомендовал против таких преобразований формата в формат.
Но если вы это сделаете, сначала преобразуйте из json в объект, затем из объекта в xml (и наоборот для обратного направления). Прямое преобразование приводит к ужасному выводу, потере информации или, возможно, к тому и другому.
Даже если ваш ответ был разбит, я рад, что он здесь. Я хочу сделать преобразование и собирался пропустить средние объекты c #, но теперь не уверен. В противном случае мне нужно было бы генерировать объекты c # на основе XSD, и, поскольку это было бы чисто только для целей конверсии, это выглядело как потраченный впустую слой (и усилия). Если у вас есть примеры или более подробно о том, как это с потерями, было бы здорово увидеть.
Крис
Не знаю, почему за это проголосовали. В настоящее время я исправляю кучу ошибок, связанных с несколькими шагами преобразования XML <-> JSON в имеющемся у нас продукте. Большинство из них сводятся к потере числовых типов при преобразовании из JSON в XML.
Риккит
Суровая правда, полезный ответ.
FailedUnitTest
@CRice Лет слишком поздно, но наличие объектов переноса в некоторой степени сохраняет схему XML. Например, как поднял Левитикон , если вы попытаетесь преобразовать документ XML с одним массивом элементов, преобразователь JSON не сможет знать, что это массив, если он не исходит из объекта переноса с типом массива.
19
1
XmlNodeConverter в Newtonsoft.JSON имеет параметр конфигурации, позволяющий избежать этой проблемы при переносе из JSON в XML обратно в JSON, но он не может
отследить
27
Спасибо за ответ Дэвида Брауна . В моем случае JSON.Net 3.5 методы преобразования находятся в статическом классе JsonConvert:
XmlNode myXmlNode =JsonConvert.DeserializeXmlNode(myJsonString);// is node not note// or .DeserilizeXmlNode(myJsonString, "root"); // if myJsonString does not have a rootstring jsonString =JsonConvert.SerializeXmlNode(myXmlNode);
Если ваши данные являются массивом, вам нужно сделать что-то вроде этого: JsonConvert.DeserializeXmlNode ("{\" Row \ ":" + json + "}", "root"). ToXmlString () в противном случае вы получите "XmlNodeConverter можно конвертировать только JSON, который начинается с объекта. " исключение.
Митчелл Скурник
Да, и вы не можете начать с числа. JsonConvert.DeserializeXmlNode ("{\" 1Row \ ":" + json + "}", "root"). Сбой ToXmlString ()
DaFi4
вышеупомянутый ответ и комментарий @mitchell помогают мне .. спасибо
Ajay2707
8
Я долго искал альтернативный код для принятого решения в надежде не использовать внешнюю сборку / проект. Благодаря исходному коду проекта DynamicJson я получил следующее :
publicXmlDocumentJsonToXML(string json){XmlDocument doc =newXmlDocument();using(var reader =JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json),XmlDictionaryReaderQuotas.Max)){XElement xml =XElement.Load(reader);
doc.LoadXml(xml.ToString());}return doc;}
Примечание: я хотел XmlDocument, а не XElement для целей xPath. Кроме того, этот код, очевидно, идет только из JSON в XML, есть разные способы сделать обратное.
Мне нужно было сделать это недавно в SQLCLR и я не мог получить зависимость, поэтому я просто укусил пулю и написал эту процедуру преобразования json в xml , она была удивительно простой и всего около 20 строк кода.
Горди
как удалить typr из xml?
взломщик
6
Вот полный код C # для преобразования XML в JSON
publicstaticclassJSon{publicstaticstringXmlToJSON(string xml){XmlDocument doc =newXmlDocument();
doc.LoadXml(xml);returnXmlToJSON(doc);}publicstaticstringXmlToJSON(XmlDocument xmlDoc){StringBuilder sbJSON =newStringBuilder();
sbJSON.Append("{ ");XmlToJSONnode(sbJSON, xmlDoc.DocumentElement,true);
sbJSON.Append("}");return sbJSON.ToString();}// XmlToJSONnode: Output an XmlElement, possibly as part of a higher arrayprivatestaticvoidXmlToJSONnode(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 =newSortedList<string,object>();// Add in all node attributesif(node.Attributes!=null)foreach(XmlAttribute attr in node.Attributes)StoreChildNode(childNodeNames, attr.Name, attr.InnerText);// Add in all nodesforeach(XmlNode cnode in node.ChildNodes){if(cnode isXmlText)StoreChildNode(childNodeNames,"value", cnode.InnerText);elseif(cnode isXmlElement)StoreChildNode(childNodeNames, cnode.Name, cnode);}// Now output all stored infoforeach(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(objectChildin 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.privatestaticvoidStoreChildNode(SortedList<string,object> childNodeNames,string nodeName,object nodeValue){// Pre-process contraction of XmlElement-sif(nodeValue isXmlElement){// 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;elseif(children.Count==1&&(children[0]isXmlText))
nodeValue =((XmlText)(children[0])).InnerText;}}// Add nodeValue to ArrayList associated with each nodeName// If nodeName doesn't exist then add itList<object>ValuesAL;if(childNodeNames.ContainsKey(nodeName)){ValuesAL=(List<object>)childNodeNames[nodeName];}else{ValuesAL=newList<object>();
childNodeNames[nodeName]=ValuesAL;}ValuesAL.Add(nodeValue);}privatestaticvoidOutputNode(string childname,object alChild,StringBuilder sbJSON,bool showNodeName){if(alChild ==null){if(showNodeName)
sbJSON.Append("\""+SafeJSON(childname)+"\": ");
sbJSON.Append("null");}elseif(alChild isstring){if(showNodeName)
sbJSON.Append("\""+SafeJSON(childname)+"\": ");string sChild =(string)alChild;
sChild = sChild.Trim();
sbJSON.Append("\""+SafeJSON(sChild)+"\"");}elseXmlToJSONnode(sbJSON,(XmlElement)alChild, showNodeName);
sbJSON.Append(", ");}// Make a string safe for JSONprivatestaticstringSafeJSON(string sIn){StringBuilder sbOut =newStringBuilder(sIn.Length);foreach(char ch in sIn){if(Char.IsControl(ch)|| ch =='\''){int ich =(int)ch;
sbOut.Append(@"\u"+ ich.ToString("x4"));continue;}elseif(ch =='\"'|| ch =='\\'|| ch =='/'){
sbOut.Append('\\');}
sbOut.Append(ch);}return sbOut.ToString();}}
Чтобы преобразовать данную строку XML в JSON, просто вызовите функцию XmlToJSON (), как показано ниже.
Вот простой фрагмент, который преобразует XmlNode (рекурсивно) в хеш-таблицу и группирует несколько экземпляров одного и того же дочернего элемента в массив (как ArrayList). Hashtable обычно принято преобразовывать в JSON большинством библиотек JSON.
Я сделал, как сказал Дэвид Браун, но получил следующее исключение.
$exception {"There are multiple root elements. Line , position ."}System.Xml.XmlException
Одним из решений может быть изменение файла XML с корневым элементом, но это не всегда необходимо, и для потока XML это также может оказаться невозможным. Мое решение ниже:
<parent><child>
Text
</child></parent><parent><child><grandchild>
Text
</grandchild><grandchild>
Text
</grandchild></child><child>
Text
</child></parent>
Ответы:
Да. Используя класс JsonConvert, который содержит вспомогательные методы для этой конкретной цели:
Документация здесь: Преобразование между JSON и XML с помощью Json.NET
источник
Да, вы можете сделать это (я делаю), но помните о некоторых парадоксах при конвертации и действуйте соответствующим образом. Вы не можете автоматически соответствовать всем возможностям интерфейса, и имеется ограниченная встроенная поддержка в управлении преобразованием - многие структуры и значения JSON не могут автоматически преобразовываться в обоих направлениях. Помните, что я использую настройки по умолчанию с библиотекой Newtonsoft JSON и библиотекой MS XML, поэтому ваш пробег может варьироваться:
XML -> JSON
{}
или вложенным массивом в[ {} {} ...]
зависимости от того, есть ли один или несколько дочерних элементов XML. Вы бы по-разному использовали эти два в JavaScript и т. Д. Различные примеры XML, соответствующего одной и той же схеме, могут таким образом создавать действительно разные структуры JSON. Вы можете добавить атрибут json: Array = 'true' к своему элементу, чтобы обойти это в некоторых (но не обязательно во всех) случаях.Новое обновление изменяет это (спасибо Джону Стори за указание на это): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
JSON -> XML
Пожалуйста, не стесняйтесь упоминать о любых других проблемах, которые вы заметили, я разработал свои собственные пользовательские процедуры для подготовки и очистки строк, когда я конвертирую туда-сюда. Ваша ситуация может требовать или не требовать подготовки / очистки. Как упоминает StaxMan, в вашей ситуации может потребоваться преобразование между объектами ... это может повлечь за собой соответствующие интерфейсы и кучу операторов case / etc для обработки предостережений, которые я упомянул выше.
источник
Вы можете сделать эти преобразования также с .NET Framework:
JSON в XML: с помощью System.Runtime.Serialization.Json
XML в JSON: с помощью System.Web.Script.Serialization
источник
Я не уверен, что в таком преобразовании есть смысл (да, многие это делают, но в основном для принудительного подвода квадратного колышка через круглое отверстие) - структурное несоответствие импеданса и преобразование с потерями. Поэтому я бы рекомендовал против таких преобразований формата в формат.
Но если вы это сделаете, сначала преобразуйте из json в объект, затем из объекта в xml (и наоборот для обратного направления). Прямое преобразование приводит к ужасному выводу, потере информации или, возможно, к тому и другому.
источник
Спасибо за ответ Дэвида Брауна . В моем случае JSON.Net 3.5 методы преобразования находятся в статическом классе JsonConvert:
источник
Я долго искал альтернативный код для принятого решения в надежде не использовать внешнюю сборку / проект. Благодаря исходному коду проекта DynamicJson я получил следующее :
Примечание: я хотел XmlDocument, а не XElement для целей xPath. Кроме того, этот код, очевидно, идет только из JSON в XML, есть разные способы сделать обратное.
источник
Вот полный код C # для преобразования XML в JSON
Чтобы преобразовать данную строку XML в JSON, просто вызовите функцию XmlToJSON (), как показано ниже.
источник
Попробуйте эту функцию. Я только написал это и не имел большого шанса проверить это, но мои предварительные тесты обещают.
источник
Вот простой фрагмент, который преобразует XmlNode (рекурсивно) в хеш-таблицу и группирует несколько экземпляров одного и того же дочернего элемента в массив (как ArrayList). Hashtable обычно принято преобразовывать в JSON большинством библиотек JSON.
источник
Cinchoo ETL - библиотека с открытым исходным кодом, позволяющая легко конвертировать Xml в JSON с помощью нескольких строк кода
Xml -> JSON:
JSON -> Xml:
Оформить статью CodeProject для дополнительной помощи.
Отказ от ответственности: я автор этой библиотеки.
источник
Я сделал, как сказал Дэвид Браун, но получил следующее исключение.
Одним из решений может быть изменение файла XML с корневым элементом, но это не всегда необходимо, и для потока XML это также может оказаться невозможным. Мое решение ниже:
Пример XML, который генерирует ошибку:
источник
Я использовал следующие методы для преобразования JSON в XML
И
Я использовал класс с именем Item для представления элементов
Оно работает....
источник
Для преобразования
JSON
строки, чтобыXML
попробовать это:Для преобразования,
XML
чтобыJSON
попробовать это:источник
используйте стороннюю библиотеку вместо написания собственного кода для анализа JSON или XML String. Если его использовать один раз, попробуйте конвертировать его онлайн. Json to Xml https://www.easycodeforall.com/Json2Xml.jsp Xml to Json https://www.easycodeforall.com/Xml2Json.jsp
источник