我一直在尝试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搜索服务并遇到此问题?
答案 0 :(得分:1)
不幸的是,这个JSON虽然有效,却无法由Json.Net直接转换为XML,原因有两个:
当JSON.Net看到以@
开头的JSON属性名称时,它会尝试将其转换为XML中的属性。 XML属性必须是一个简单的值(字符串,整数等);它不可能是一个复杂的对象。在JSON中,@search.highlights
属性的值显然是一个复杂的对象,因此无法将其转换为XML属性。这就是您收到错误的原因。
XML标记名称不能包含@
。假设我们能够超越第一个问题(例如,从@
中删除前导@search.highlights
),当尝试将kbTitle@odata.type
属性转换为XML标记时,将抛出另一个错误事实上它在中间包含@
。
我想到了几种可能的解决方案:
快速而肮脏的方法是在将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>
希望这有帮助。