Census Geocoder JSON输出在C#中使用JSON.net转换为Xml数据集

我在Visual Studio 2012中创建一个.Net应用程序,用于查询我的SQL dB中的地址表,并使用Census Geocoding API返回每个地址的特定MSA。 我有现有的dB查询代码,但我在将Census API的Json输出转换为Xml数据集时遇到问题。 我正在使用Json.net序列化json输出,然后反序列化为.net以加载到XmlDocument中。 不幸的是,我一直收到XmlException错误:

根级别的数据无效。 第1行,第1位

细节:

System.Xml.XmlException未处理HResult = -2146232000
消息=根级别的数据无效。 第1行,第1位。
Source = System.Xml LineNumber = 1 LinePosition = 1 SourceUri =“”
StackTrace:位于System.Xml.Xml.Xml.Xh处的System.Xml.XmlTextReaderImpl.Throw(String res,String arg)的System.Xml.XmlTextReaderImpl.Throw(Exception e),位于System.Xml.XmlTextRemplImpl.ParseDocumentContent()的System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()处位于System.Xml.XmlDocument.LoadXml(String xml)的System.Xml.XmlDocument.Load(XmlReader reader)的System.Xml.XmlLoader.Load(XmlDocument doc,XmlReader reader,Boolean preserveWhitespace)中的System.Xml.XmlTextReaderImpl.Read() )在C:\ Users \ jdsmith \ Documents \ Visual Studio 2012 \ Projects \ C#\ MSA_Application_v2 \ MSA_Application_v2 \ Model \ Program.cs中的ConsoleApplication1.Program.Main(String [] args):System.AppDomain._nExecuteAssembly中的第54行( System.Threading.ThreadHelper.ThreadStart_Context(对象状态)中的Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()中的System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)中的RuntimeAssembly程序集,String [] args)在System.Threading.ExecutionContext.RunIntern System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)中的al(ExecutionContext executionContext,ContextCallback回调,Object state,Boolean preserveSyncCtx) System.Threading.ThreadHelper.ThreadStart()中的对象状态:InnerException:

我相信Json或Xml需要进一步格式化,但我不知道如何。 而且,我确信我对自己太难了……如果有更好的方法,我全都是耳朵。

这是我用来测试的geolookup示例:

http://geocoding.geo.census.gov/geocoder/geographies/address?street=4600+Silver+Hill+Rd&city=Suitland&state=MD&benchmark=Public_AR_Census2010&vintage=Census2010_Census2010&layers=14&format=json

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Threading.Tasks; using System.Data; using System.Net; using System.IO; using System.Xml; using System.Runtime.Serialization.Json; using System.Xml.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace ConsoleApplication1 { class Program { private static string geoRT = "geographies"; private static string geoST = "address"; private static string geoStreet = "4600+Silver+Hill+Rd"; private static string geoCity = "Suitland"; private static string geoState = "MD"; private static string geoZip = "20746"; private static string geoBM = "Public_AR_Census2010"; private static string geoVin = "Census2010_Census2010"; private static string geoLayer = "all"; private static string geoFormat = "json"; static void Main(string[] args) { StringBuilder geoRelURI = new StringBuilder(); geoRelURI.AppendFormat(@"{0}/{1}?street={2}&city={3}&state={4}&zip={5}&benchmark={6}&vintage={7}&layers={8}&format={9}" , geoRT, geoST, geoStreet, geoCity, geoState, geoZip, geoBM, geoVin, geoLayer, geoFormat); Uri geoBaseURI = new Uri("http://geocoding.geo.census.gov/geocoder/"); Uri geoURI = new Uri(geoBaseURI, geoRelURI.ToString()); //Console.WriteLine(geoURI); //Console.ReadLine(); WebRequest geoRequest = WebRequest.Create(geoURI); WebResponse geoResponse = geoRequest.GetResponse(); Stream geoDataStream = geoResponse.GetResponseStream(); StreamReader geoReader = new StreamReader(geoDataStream); string geoString = geoReader.ReadToEnd(); var jsonConvert = JsonConvert.SerializeObject(geoString); string jsonString = jsonConvert.ToString(); var xmlConvert = JsonConvert.DeserializeObject(jsonString); string xmlString = xmlConvert.ToString(); XmlDocument geoXMLDoc = new XmlDocument(); geoXMLDoc.LoadXml(xmlString); XmlWriterSettings xmlSettings = new XmlWriterSettings(); xmlSettings.Indent = true; XmlWriter geoXMLWriter = XmlWriter.Create("geoXML.xml", xmlSettings); geoXMLDoc.Save(geoXMLWriter); Console.Write("
" + geoXMLDoc.OuterXml); //Console.WriteLine(xmlString); //Console.ReadLine(); geoDataStream.Close(); geoResponse.Close(); } } }

首先,您将JSON字符串传递给geoXMLDoc.LoadXml() 。 那不行。 你想要做的是通过JsonConvert.DeserializeXmlNode将JSON转换为XmlDocument

但是,某些JSON属性包含在XML名称中使用的字符,在特定的空格中:

 {"Census Blocks":[{"BLKGRP":"1", 

这似乎导致DeserializeXmlNode抛出exception。 因此,您需要重命名名称:

  var obj = JObject.Parse(geoString); foreach (var fix in (from property in obj.Descendants().OfType() let newName = XmlConvert.EncodeLocalName(property.Name.Replace(" ", "")) where newName != property.Name select new { Old = property, New = new JProperty(newName, property.Value) }) .ToList()) { fix.Old.Replace(fix.New); } var xmldoc = JsonConvert.DeserializeXmlNode(obj.ToString()); 

需要您将尝试加载的内容发布到XmlDocument中。 这就是你遇到问题的地方。 如果您尝试加载从Web调用获得的JSON,它将无法工作,如果您(我怀疑)使用JSON.Net将JSON转换为Xml,则Xml缺少XmlDocument所需的内容。 可能是Xml声明行,或者您的xml片段可能不包含根节点。 在没有看到xml的情况下,我们无法详细说明丢失或格式错误的内容。