Comecei a usar o Json.NET para converter uma string no formato JSON em objeto ou vice-versa. Não tenho certeza no framework Json.NET, é possível converter uma string no formato JSON para XML e vice-versa?
Observe como StaxMan disse, se houver ex. espaço no nó do elemento, ele será ignorado pelo xml. Por ex. "ID do aluno": 11000 não estará no resultado xml, por causa do espaço no nome da propriedade. O xml não aceita ter espaço no nó do elemento.
Daniel B
Respostas:
424
Sim. Usando a classe JsonConvert, que contém métodos auxiliares para este fim preciso:
// 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);
Apenas para sua informação, há um problema em potencial aqui. Quando eu estava transformando uma matriz de nós xml em json, ela estava criando uma matriz em json. Mas, quando executo uma matriz de nós xml com contagem de 1, a conversão json não formata mais uma matriz. Uma matriz xml com um único elemento é perdida na tradução aqui.
Levitikon 22/03/12
3
Surpresa surpresa - essa é a impedância entre XML e JSON e a razão pela qual (IMO) não é uma boa ideia converter diretamente entre os dois. Mas, hey, há muitas devs que Discordo aqui (como por downvotes sobre a minha resposta) e não se importam essas conversões de dados acidentais ou perda de dados potencial ...
StaxMan
7
@ StaxMan: Acho que todos podem concordar que não há uma maneira padronizada de representar um documento XML no formato JSON. Sua resposta provavelmente foi diminuída porque na verdade não respondeu à pergunta. O OP não estava perguntando se ele deveria fazer a conversão, mas se poderia fazê-lo usando as ferramentas que já estavam à sua disposição.
David Brown
46
Sim, você pode fazer isso (eu faço), mas esteja ciente de alguns paradoxos ao converter e manipule adequadamente. Você não pode estar em conformidade automaticamente com todas as possibilidades da interface e há um suporte interno limitado no controle da conversão - muitas estruturas e valores JSON não podem ser convertidos automaticamente nos dois sentidos. Lembre-se de que estou usando as configurações padrão das bibliotecas Newtonsoft JSON e MS XML, portanto, sua milhagem pode variar:
XML -> JSON
Todos os dados se tornam dados de cadeia de caracteres (por exemplo, você sempre obtém "false", não false ou "0", não 0 ). Obviamente, o JavaScript os trata de maneira diferente em determinados casos.
Os elementos filhos podem se tornar objeto {}aninhado OU matriz aninhada, [ {} {} ...]dependendo se houver apenas um ou mais de um elemento filho XML. Você consumiria esses dois de maneira diferente em JavaScript etc. Exemplos diferentes de XML em conformidade com o mesmo esquema podem produzir estruturas JSON realmente diferentes dessa maneira. Você pode adicionar o atributo json: Array = 'true' ao seu elemento para solucionar isso em alguns casos (mas não necessariamente em todos).
Seu XML deve ser razoavelmente bem formado, notei que ele não precisa estar em conformidade com o padrão W3C, mas 1. você deve ter um elemento raiz e 2. não pode iniciar nomes de elementos com números são dois dos padrões XML impostos Eu descobri ao usar as bibliotecas Newtonsoft e MS.
Nas versões anteriores, os elementos em branco não são convertidos para JSON. Eles são ignorados. Um elemento em branco não se torna "elemento": null
Você precisa de um objeto de nível superior que será convertido em um elemento XML raiz ou o analisador falhará.
Os nomes dos seus objetos não podem começar com um número, pois não podem ser convertidos em elementos (XML é tecnicamente ainda mais rigoroso que isso), mas eu posso 'fugir' com a quebra de algumas das outras regras de nomenclatura de elementos.
Por favor, sinta-se à vontade para mencionar outros problemas que tenha notado. Desenvolvi minhas próprias rotinas personalizadas para preparar e limpar as seqüências de caracteres à medida que eu me converto. Sua situação pode ou não exigir preparação / limpeza. Como o StaxMan menciona, sua situação pode realmente exigir a conversão entre objetos ... isso pode implicar interfaces apropriadas e várias instruções de caso / etc para lidar com as advertências mencionadas acima.
Este! Boa elaboração do que minha resposta curta (e que foi bastante prejudicada em algum momento) foi baseada - existem muitas armadilhas se você fizer uma conversão direta cega. Eles podem não estar bloqueando problemas para uso específico, mas também podem ser muito desagradáveis para outros.
precisa saber é
1
Em relação a # 4 em XML -> JSON: você pode usar a propriedade NullValueHandling para especificar que valores nulos devem ser incluídos explicitamente - newtonsoft.com/json/help/html/…
Jon Story
A descrição do problema neste comentário se aplica bem a TODAS as implementações de algoritmos que convertem JSON em XML ou o inverso. Uma vez que se aceita que não é possível alcançar simultaneamente uma fidelidade bidirecional perfeita, e ao mesmo tempo éter "parte" ou "restrição" (esquema / formato pré-ditado), entrada e saída. - no caso geral.
DALDEI 27/04/19
33
Você pode fazer essas conversões também com o .NET Framework:
Eu recebo um erro no GetXmlData "O nome 'GetXmlData' não existe no contexto atual" Existe uma diretiva de uso que está faltando?
TimSmith-Aardwolf
4
@ TimSmith-Aardwolf, Aqui está todo o código que você precisa. Para usar System.Web.Script.Serialization, é necessário adicionar o assembly System.Web.Extensions em References.
Termininja 21/07
@Termininja, JSON to XML, me dando o tipo também, como remover isso?
Cracker
@Termininja, Perfeito, Obrigado.
Cracker
30
Não tenho certeza de que haja sentido nessa conversão (sim, muitos fazem isso, mas principalmente para forçar um pino quadrado através do orifício redondo) - há incompatibilidade de impedância estrutural e a conversão é com perda. Então, eu recomendaria essas transformações de formato para formato.
Mas se você fizer isso, primeiro converta de json para objeto, depois de objeto para xml (e vice-versa para direção reversa). Fazer transformações diretas leva a resultados feios, perda de informações ou possivelmente a ambos.
Mesmo que sua resposta tenha sido esmagada, fico feliz que ela esteja aqui. Eu quero fazer a conversão e estava pensando em pular os objetos do meio c #, mas agora não tenho tanta certeza. Eu precisaria gerar objetos c # baseados no XSD de outra forma e, como seria apenas para fins de conversão, parecia uma camada desperdiçada (e esforço). Se você tiver exemplos ou mais detalhes de como é uma perda, seria ótimo ver isso.
CRice 01/08/19
Não sei por que isso foi prejudicado. Atualmente, estou corrigindo vários bugs relacionados a várias etapas de transformação XML <-> JSON em um produto que temos. A maioria está relacionada à perda de tipos numéricos ao converter de JSON para XML.
Rikkit
A dura verdade, resposta útil.
FailedUnitTest
@CRice Anos muito tarde, mas ter os objetos de transferência preserva o esquema XML, até certo ponto. Por exemplo, conforme apresentado pela Levitikon , se você tentar converter um documento XML com uma matriz de elemento único, a conversão JSON não poderá saber que é uma matriz, a menos que seja proveniente de um objeto de transferência com um tipo de matriz.
jpaugh
1
De Newtonsoft.JSON XmlNodeConverter tem uma opção de configuração para evitar esse problema quando da transferência de JSON para trás XML para JSON, mas não pode pegar casos em que o formato original é XML
jpaugh
27
Obrigado pela resposta de David Brown . No meu caso do JSON.Net 3.5, os métodos convert estão na classe estática 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);
Se seus dados forem uma matriz, será necessário fazer algo assim: JsonConvert.DeserializeXmlNode ("{\" Row \ ":" + json + "}", "root"). ToXmlString () caso contrário, você receberá um "XmlNodeConverter só pode converter JSON que começa com um objeto ". exceção.
Mitchell Skurnik
Sim, e você não pode começar com um número. JsonConvert.DeserializeXmlNode ("{\" 1Row \ ":" + json + "}", "root"). ToXmlString () falhará
DaFi4
a resposta acima e @mitchell comentário me ajuda .. obrigado
Ajay2707
8
Procurei por um longo tempo para encontrar código alternativo para a solução aceita, na esperança de não usar um assembly / projeto externo. Eu vim com o seguinte graças ao código fonte do projeto 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;}
Nota: Eu queria um XmlDocument em vez de um XElement para fins de xPath. Além disso, esse código obviamente só vai de JSON para XML; existem várias maneiras de fazer o oposto.
Eu precisava fazer isso recentemente em um SQLCLR e não podia depender de uma dependência, então apenas mordi a bala e escrevi essa rotina de conversão de json para xml , era surpreendentemente simples e tinha apenas 20 linhas de código.
Gordy
Como remover typr de xml?
Cracker
6
Aqui está o código c # completo para converter xml para 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();}}
Para converter uma determinada string XML em JSON, basta chamar a função XmlToJSON () como abaixo.
Aqui está um trecho simples que converte um XmlNode (recursivamente) em uma hashtable e agrupa várias instâncias do mesmo filho em uma matriz (como um ArrayList). O Hashtable geralmente é aceito para converter em JSON pela maioria das bibliotecas JSON.
Eu fiz como David Brown disse, mas recebi a seguinte exceção.
$exception {"There are multiple root elements. Line , position ."}System.Xml.XmlException
Uma solução seria modificar o arquivo XML com um elemento raiz, mas isso nem sempre é necessário e, para um fluxo XML, também pode não ser possível. Minha solução abaixo:
<parent><child>
Text
</child></parent><parent><child><grandchild>
Text
</grandchild><grandchild>
Text
</grandchild></child><child>
Text
</child></parent>
Respostas:
Sim. Usando a classe JsonConvert, que contém métodos auxiliares para este fim preciso:
Documentação aqui: Convertendo entre JSON e XML com Json.NET
fonte
Sim, você pode fazer isso (eu faço), mas esteja ciente de alguns paradoxos ao converter e manipule adequadamente. Você não pode estar em conformidade automaticamente com todas as possibilidades da interface e há um suporte interno limitado no controle da conversão - muitas estruturas e valores JSON não podem ser convertidos automaticamente nos dois sentidos. Lembre-se de que estou usando as configurações padrão das bibliotecas Newtonsoft JSON e MS XML, portanto, sua milhagem pode variar:
XML -> JSON
{}
aninhado OU matriz aninhada,[ {} {} ...]
dependendo se houver apenas um ou mais de um elemento filho XML. Você consumiria esses dois de maneira diferente em JavaScript etc. Exemplos diferentes de XML em conformidade com o mesmo esquema podem produzir estruturas JSON realmente diferentes dessa maneira. Você pode adicionar o atributo json: Array = 'true' ao seu elemento para solucionar isso em alguns casos (mas não necessariamente em todos).Uma nova atualização altera isso (Agradecemos a Jon Story por apontar): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
JSON -> XML
Por favor, sinta-se à vontade para mencionar outros problemas que tenha notado. Desenvolvi minhas próprias rotinas personalizadas para preparar e limpar as seqüências de caracteres à medida que eu me converto. Sua situação pode ou não exigir preparação / limpeza. Como o StaxMan menciona, sua situação pode realmente exigir a conversão entre objetos ... isso pode implicar interfaces apropriadas e várias instruções de caso / etc para lidar com as advertências mencionadas acima.
fonte
Você pode fazer essas conversões também com o .NET Framework:
JSON para XML: usando System.Runtime.Serialization.Json
XML para JSON: usando System.Web.Script.Serialization
fonte
Não tenho certeza de que haja sentido nessa conversão (sim, muitos fazem isso, mas principalmente para forçar um pino quadrado através do orifício redondo) - há incompatibilidade de impedância estrutural e a conversão é com perda. Então, eu recomendaria essas transformações de formato para formato.
Mas se você fizer isso, primeiro converta de json para objeto, depois de objeto para xml (e vice-versa para direção reversa). Fazer transformações diretas leva a resultados feios, perda de informações ou possivelmente a ambos.
fonte
Obrigado pela resposta de David Brown . No meu caso do JSON.Net 3.5, os métodos convert estão na classe estática JsonConvert:
fonte
Procurei por um longo tempo para encontrar código alternativo para a solução aceita, na esperança de não usar um assembly / projeto externo. Eu vim com o seguinte graças ao código fonte do projeto DynamicJson :
Nota: Eu queria um XmlDocument em vez de um XElement para fins de xPath. Além disso, esse código obviamente só vai de JSON para XML; existem várias maneiras de fazer o oposto.
fonte
Aqui está o código c # completo para converter xml para json
Para converter uma determinada string XML em JSON, basta chamar a função XmlToJSON () como abaixo.
fonte
Tente esta função. Acabei de escrever e não tive muita chance de testá-lo, mas meus testes preliminares são promissores.
fonte
Aqui está um trecho simples que converte um XmlNode (recursivamente) em uma hashtable e agrupa várias instâncias do mesmo filho em uma matriz (como um ArrayList). O Hashtable geralmente é aceito para converter em JSON pela maioria das bibliotecas JSON.
fonte
Cinchoo ETL - uma biblioteca de código aberto disponível para fazer a conversão de XML para JSON facilmente com poucas linhas de código
Xml -> JSON:
JSON -> XML:
Artigo CheckPro CodeProject para obter ajuda adicional.
Disclaimer: Eu sou o autor desta biblioteca.
fonte
Eu fiz como David Brown disse, mas recebi a seguinte exceção.
Uma solução seria modificar o arquivo XML com um elemento raiz, mas isso nem sempre é necessário e, para um fluxo XML, também pode não ser possível. Minha solução abaixo:
Exemplo de XML que gera o erro:
fonte
Eu usei os métodos abaixo para converter o JSON em XML
E
Eu usei a classe chamada Item para representar os elementos
Funciona....
fonte
Para converter
JSON
string paraXML
tentar isso:Para converter
XML
paraJSON
tentar isso:fonte
use a biblioteca de terceiros, em vez de escrever o próprio código para analisar JSON ou XML String. Se for usado apenas uma vez, tente convertê-lo online. Json para Xml https://www.easycodeforall.com/Json2Xml.jsp Xml para Json https://www.easycodeforall.com/Xml2Json.jsp
fonte