无法从令牌类型“StartObject”获取XML字符串值

时间:2014-08-27 22:03:41

标签: c# xml json azure json.net

我一直在尝试Azure最近宣布的搜索服务,并使用JSON.Net将生成的JSON输出转换为XML。它通常可以正常工作,除非添加突出显示参数时出现Cannot get an XML string value from token type 'StartObject'. Path 'value[0].@search.highlights'错误消息。 highlight参数添加了解析器似乎不喜欢的@search.highlights。我还检查了jsonvalidatortool.com上的JSON输出,结果是有效的。

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

{
  "value":
    [
      {
        "@search.score": 1.2591839,
        "@search.highlights": 
          {
            "kbTitle@odata.type": "#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 个答案:

答案 0 :(得分:1)

不幸的是,这个JSON虽然有效,却无法由Json.Net直接转换为XML,原因有两个:

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

  2. XML标记名称不能包含@。假设我们能够超越第一个问题(例如,从@中删除前导@search.highlights),当尝试将kbTitle@odata.type属性转换为XML标记时,将抛出另一个错误事实上它在中间包含@

  3. 我想到了几种可能的解决方案:

    快速而肮脏的方法是在将JSON转换为XML之前尝试对JSON进行字符串替换。如果问题区域只是我突出显示的那两个特定属性名称,那么您可以专门定位它们以删除或替换@字符,使其更适合XML,如下划线_。如果JSON更具动态性,使得问题属性名称变化很大,则此方法不太可能正常工作。您比我更了解您的数据 - 我对Azure搜索服务并不熟悉。

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

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

    希望这有帮助。