2014-08-27 96 views
1

我一直在尝试Azure最近宣布的搜索服务,并使用JSON.Net将生成的JSON输出转换为XML。它通常工作正常,除了添加突出显示参数时,我得到一个Cannot get an XML string value from token type 'StartObject'. Path 'value[0][email protected]'错误消息。突出显示参数添加解析器似乎不喜欢的@search.highlights。我还检查了jsonvalidatortool.com上的JSON输出,它的结果是有效的。无法从令牌类型'StartObject'获取XML字符串值

从Azure的搜索服务收到的JSON如下:

{ 
    "value": 
    [ 
     { 
     "@search.score": 1.2591839, 
     "@search.highlights": 
      { 
      "[email protected]": "#Collection(String)", 
      "kbTitle": [ 
       "No Video/Blank Screen When Attempting to Stream from <em>Netflix</em>" 
      ] 
      }, 
     "kbID":"10", 
     "kbTitle":"No Video/Blank Screen When Attempting to Stream from Netflix" 
     } 
    ] 
} 

任何人试图与JSON.Net新Azure的搜索服务,体验这个问题?

回答

1

不幸的是,这个JSON,而有效的,不能直接通过Json.Net的原因有两个转换为XML:

  1. 当JSON.Net看到一个JSON属性名称以@,它会尝试转换它到XML中的一个属性。 XML属性必须是一个简单的值(字符串,整数等);它不可能是一个复杂的对象。在JSON中,@search.highlights属性的值显然是一个复杂对象,因此无法将其转换为XML属性。这就是你收到错误的原因。

  2. XML标签名称不能包含@。假设我们能够克服第一个问题(例如,通过从@search.highlights中删除前导@),则在尝试将[email protected]属性转换为XML标记时,会出现另一个错误,因为它包含中间的@

几个可能的解决方案浮现在脑海中:

快速和肮脏的方法是尝试做一个字符串的JSON将其转换为XML之前更换。如果问题区域只是我突出显示的那两个特定属性名称,那么您可以专门将它们作为目标,以便使用更加适合XML的内容(如下划线_)删除或替换@字符。如果JSON更具动态性,以至于问题属性名称高度可变,那么这种方法不太可能正常工作。您比我更了解您的数据 - 我并不熟悉Azure搜索服务。

一个更强大的解决方案是将JSON反序列化为JObject,然后手动遍历JObject并将其按照您需要的方式转换为XML。您可以省略不需要的部分,更改属性/标签名称等。当然,这里假定您熟悉Json.Net的LINQ-to-JSON API(JObject,JTokens,JArrays等),并且熟悉与类.NET框架中的System.Xml namespace

另一个想法是创建一个中间模型类,将JSON反序列化为该类型(因此您可以使用[JsonProperty]属性来处理时髦的属性名称),然后使用XmlSerializer将该模型转换为XML。

希望这会有所帮助。

+0

你真棒!感谢您的详细解释和建议的解决方案,我现在对该问题以及如何处理问题有了很好的理解。 – Kevin 2014-08-28 17:40:44

+0

没问题。很高兴我能帮上忙! – 2014-08-28 17:42:25

相关问题