1

我正在 Visual Studio 2012 中创建一个 .Net 应用程序,该应用程序在我的 SQL dB 中查询地址表,并使用人口普查地理编码 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.XmlTextReaderImpl.Throw(String res, String arg) 在 System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace() 在 System.Xml.XmlTextReaderImpl.ParseDocumentContent() 在 System.Xml.XmlTextReaderImpl.Throw(Exception e) 在 System.Xml.XmlTextReaderImpl.ParseDocumentContent() 在System.Xml.XmlTextReaderImpl.Read() at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) at System.Xml.XmlDocument.Load(XmlReader reader) at System.Xml.XmlDocument.LoadXml(String xml ) 在 ConsoleApplication1.Program.Main(String[] args) 在 c:\Users\jdsmith\Documents\Visual Studio 2012\Projects\C#\MSA_Application_v2\MSA_Application_v2\Model\Program.cs: System.AppDomain._nExecuteAssembly ( RuntimeAssembly 程序集,String[] args) 在 System.AppDomain。Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback 的 ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) Threading.ThreadHelper.ThreadStart() 内部异常:HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart() InnerException 的 ContextCallback 回调,对象状态,布尔值 preserveSyncCtx):HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart() InnerException 的 ContextCallback 回调,对象状态,布尔值 preserveSyncCtx):Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart () 内部异常:Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart () 内部异常:

我相信 Json 或 Xml 都需要进一步格式化,但我不知道如何。另外,我确定我自己太难了……如果有更好的方法,我会全神贯注。

这是我用来测试的示例地理查询:

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("<BR>" + geoXMLDoc.OuterXml);

            //Console.WriteLine(xmlString);
            //Console.ReadLine();

            geoDataStream.Close();
            geoResponse.Close();

        }
    }
}
4

2 回答 2

1

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

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

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

似乎这会导致DeserializeXmlNode引发异常。因此,您需要重命名名称:

        var obj = JObject.Parse(geoString);
        foreach (var fix in (from property in obj.Descendants().OfType<JProperty>()
                             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());
于 2015-05-07T19:35:20.923 回答
0

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

于 2015-05-07T17:34:35.857 回答