XML 反序列化无法解析属性类型
XML deserialization cannot resolve attribute type
我正在从事一个项目,我通过 REST 和 Comet 语义与 API 服务通信。
XML
所以,手头的问题。
当我尝试反序列化以下 XML.
时收到此错误
Error at resolve type "xsi:SubscriptionEvent"
NetBike.Xml.TypeResolvers.XmlTypeResolveException
注意:我用的是NetBike,但是默认的xml格式器也有这个错误
<?xml version="1.0" encoding="UTF-8"?>
<xsi:Event
xsi1:type="xsi:SubscriptionEvent"
xmlns:xsi="http://schema.broadsoft.com/xsi"
xmlns:xsi1="http://www.w3.org/2001/XMLSchema-instance">
<xsi:eventID>0787e727-e73d-43e0-a7b1-e968ba72ea53</xsi:eventID>
<xsi:sequenceNumber>1</xsi:sequenceNumber>
<xsi:userId>11111111@voip.company.domain</xsi:userId>
<xsi:externalApplicationId>NewClient</xsi:externalApplicationId>
<xsi:subscriptionId>24def51b-21fb-4d60-a1ef-67477dcafcfb</xsi:subscriptionId>
<xsi:channelId>575cfe44-2cc7-4cf5-bc05-bcc462bcbb02</xsi:channelId>
<xsi:targetId>22222222@voip.company.domain</xsi:targetId>
<xsi:eventData xsi1:type="xsi:ACDSubscriptionEvent"/>
</xsi:Event>
我不是 XML "Jedi knight",但我了解基础知识。
错误告诉我类型有问题 xsi1:type="xsi:SubscriptionEvent" 这是根 xml(事件)元素上的属性,这是有问题的三个属性。
xsi1:type="xsi:SubscriptionEvent"
xmlns:xsi="http://schema.broadsoft.com/xsi"
xmlns:xsi1="http://www.w3.org/2001/XMLSchema-instance"
C#Class
我使用的是 C#,直到现在我都可以根据开发时返回给我的 XML 创建等效的 classes。
如果我取出 "bad data" 则可以避免异常。
Event Class(我在 Web API V2 环境中使用它,所以从技术上讲它是一个模型)
[XmlRoot(ElementName = "Event", Namespace = "http://schema.broadsoft.com/xsi")]
public class Event
{
[XmlElement(ElementName = "eventID", Namespace = "http://schema.broadsoft.com/xsi")]
public string EventID { get; set; }
[XmlElement(ElementName = "sequenceNumber", Namespace = "http://schema.broadsoft.com/xsi")]
public string SequenceNumber { get; set; }
[XmlElement(ElementName = "userId", Namespace = "http://schema.broadsoft.com/xsi")]
public string UserId { get; set; }
[XmlElement(ElementName = "externalApplicationId", Namespace = "http://schema.broadsoft.com/xsi")]
public string ExternalApplicationId { get; set; }
[XmlElement(ElementName = "subscriptionId", Namespace = "http://schema.broadsoft.com/xsi")]
public string SubscriptionId { get; set; }
[XmlElement(ElementName = "channelId", Namespace = "http://schema.broadsoft.com/xsi")]
public string ChannelId { get; set; }
[XmlElement(ElementName = "targetId", Namespace = "http://schema.broadsoft.com/xsi")]
public string TargetId { get; set; }
[XmlElement(ElementName = "eventData", Namespace = "http://schema.broadsoft.com/xsi")]
public EventData eventData { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string xsi { get; set; }
[XmlAttribute(AttributeName = "xsi1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi1 { get; set; }
[XmlRoot(ElementName = "eventData", Namespace = "http://schema.broadsoft.com/xsi")]
public class EventData
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
}
}
这个class主要是从http://xmltocsharp.azurewebsites.net/生成的
(这大大加快了这项原本枯燥的任务)
有效XML?
当我通过不同的 XML 验证器 运行 XML 时,我得到不同的响应,有些验证 XML 正常,有些则没有。
- http://www.xmlvalidation.com: 失败
- http://www.validome.org/xml/validate: 失败
- http://codebeautify.org/xmlvalidate:好的
对我来说,我很难理解这个结构究竟应该如何工作。
看起来 type 属性应该建立在 xsi1 属性之上,但我尝试的一切都失败了。
我最后的办法是将响应作为字符串读取,然后去掉烦人的 XML 以便它可以正确反序列化。
此致。
一位急需帮助的有点沮丧的开发人员。
我认为出现混淆是因为 xsi:type
是 XML 架构的一部分并定义了各种元素的类型。您正试图将其视为普通属性,而序列化程序正试图使用它来确定将数据映射到哪些对象。它要查找的对象未在模型中定义。
本质上,您需要根据 XML 暗示的类型层次结构对 classes 进行建模。所以你有一个基础 Event
class 和一个 SubscriptionEvent
sub-class,你有一个基础 EventData
class 和一个 ACDSubscriptionEvent
子class.
请注意(至少 XmlSerializer
),您可以省略很多名称空间,因为它们是从父级继承的。您可能比我更了解层次结构,因此可以将某些属性移动到基础 class 等中。理想情况下,您将拥有 XML 架构文件 (.xsd) 并且能够使用 xsd.exe
生成 classes,但这将适用于给定的 XML:
[XmlInclude(typeof(SubscriptionEvent))]
[XmlRoot(Namespace = "http://schema.broadsoft.com/xsi")]
public abstract class Event
{
}
[XmlType(Namespace = "http://schema.broadsoft.com/xsi")]
public class SubscriptionEvent : Event
{
[XmlElement(ElementName = "eventID")]
public string EventID { get; set; }
[XmlElement(ElementName = "sequenceNumber")]
public string SequenceNumber { get; set; }
[XmlElement(ElementName = "userId")]
public string UserId { get; set; }
[XmlElement(ElementName = "externalApplicationId")]
public string ExternalApplicationId { get; set; }
[XmlElement(ElementName = "subscriptionId")]
public string SubscriptionId { get; set; }
[XmlElement(ElementName = "channelId")]
public string ChannelId { get; set; }
[XmlElement(ElementName = "targetId")]
public string TargetId { get; set; }
[XmlElement(ElementName = "eventData")]
public EventData EventData { get; set; }
}
[XmlInclude(typeof(ACDSubscriptionEvent))]
public abstract class EventData
{
}
[XmlType(Namespace = "http://schema.broadsoft.com/xsi")]
public class ACDSubscriptionEvent : EventData
{
}
有关工作演示(使用 XmlSerializer
),请参阅 this fiddle。
我正在从事一个项目,我通过 REST 和 Comet 语义与 API 服务通信。
XML
所以,手头的问题。 当我尝试反序列化以下 XML.
时收到此错误Error at resolve type "xsi:SubscriptionEvent" NetBike.Xml.TypeResolvers.XmlTypeResolveException
注意:我用的是NetBike,但是默认的xml格式器也有这个错误
<?xml version="1.0" encoding="UTF-8"?>
<xsi:Event
xsi1:type="xsi:SubscriptionEvent"
xmlns:xsi="http://schema.broadsoft.com/xsi"
xmlns:xsi1="http://www.w3.org/2001/XMLSchema-instance">
<xsi:eventID>0787e727-e73d-43e0-a7b1-e968ba72ea53</xsi:eventID>
<xsi:sequenceNumber>1</xsi:sequenceNumber>
<xsi:userId>11111111@voip.company.domain</xsi:userId>
<xsi:externalApplicationId>NewClient</xsi:externalApplicationId>
<xsi:subscriptionId>24def51b-21fb-4d60-a1ef-67477dcafcfb</xsi:subscriptionId>
<xsi:channelId>575cfe44-2cc7-4cf5-bc05-bcc462bcbb02</xsi:channelId>
<xsi:targetId>22222222@voip.company.domain</xsi:targetId>
<xsi:eventData xsi1:type="xsi:ACDSubscriptionEvent"/>
</xsi:Event>
我不是 XML "Jedi knight",但我了解基础知识。 错误告诉我类型有问题 xsi1:type="xsi:SubscriptionEvent" 这是根 xml(事件)元素上的属性,这是有问题的三个属性。
xsi1:type="xsi:SubscriptionEvent"
xmlns:xsi="http://schema.broadsoft.com/xsi"
xmlns:xsi1="http://www.w3.org/2001/XMLSchema-instance"
C#Class
我使用的是 C#,直到现在我都可以根据开发时返回给我的 XML 创建等效的 classes。 如果我取出 "bad data" 则可以避免异常。
Event Class(我在 Web API V2 环境中使用它,所以从技术上讲它是一个模型)
[XmlRoot(ElementName = "Event", Namespace = "http://schema.broadsoft.com/xsi")]
public class Event
{
[XmlElement(ElementName = "eventID", Namespace = "http://schema.broadsoft.com/xsi")]
public string EventID { get; set; }
[XmlElement(ElementName = "sequenceNumber", Namespace = "http://schema.broadsoft.com/xsi")]
public string SequenceNumber { get; set; }
[XmlElement(ElementName = "userId", Namespace = "http://schema.broadsoft.com/xsi")]
public string UserId { get; set; }
[XmlElement(ElementName = "externalApplicationId", Namespace = "http://schema.broadsoft.com/xsi")]
public string ExternalApplicationId { get; set; }
[XmlElement(ElementName = "subscriptionId", Namespace = "http://schema.broadsoft.com/xsi")]
public string SubscriptionId { get; set; }
[XmlElement(ElementName = "channelId", Namespace = "http://schema.broadsoft.com/xsi")]
public string ChannelId { get; set; }
[XmlElement(ElementName = "targetId", Namespace = "http://schema.broadsoft.com/xsi")]
public string TargetId { get; set; }
[XmlElement(ElementName = "eventData", Namespace = "http://schema.broadsoft.com/xsi")]
public EventData eventData { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string xsi { get; set; }
[XmlAttribute(AttributeName = "xsi1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi1 { get; set; }
[XmlRoot(ElementName = "eventData", Namespace = "http://schema.broadsoft.com/xsi")]
public class EventData
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
}
}
这个class主要是从http://xmltocsharp.azurewebsites.net/生成的 (这大大加快了这项原本枯燥的任务)
有效XML?
当我通过不同的 XML 验证器 运行 XML 时,我得到不同的响应,有些验证 XML 正常,有些则没有。
- http://www.xmlvalidation.com: 失败
- http://www.validome.org/xml/validate: 失败
- http://codebeautify.org/xmlvalidate:好的
对我来说,我很难理解这个结构究竟应该如何工作。 看起来 type 属性应该建立在 xsi1 属性之上,但我尝试的一切都失败了。
我最后的办法是将响应作为字符串读取,然后去掉烦人的 XML 以便它可以正确反序列化。
此致。 一位急需帮助的有点沮丧的开发人员。
我认为出现混淆是因为 xsi:type
是 XML 架构的一部分并定义了各种元素的类型。您正试图将其视为普通属性,而序列化程序正试图使用它来确定将数据映射到哪些对象。它要查找的对象未在模型中定义。
本质上,您需要根据 XML 暗示的类型层次结构对 classes 进行建模。所以你有一个基础 Event
class 和一个 SubscriptionEvent
sub-class,你有一个基础 EventData
class 和一个 ACDSubscriptionEvent
子class.
请注意(至少 XmlSerializer
),您可以省略很多名称空间,因为它们是从父级继承的。您可能比我更了解层次结构,因此可以将某些属性移动到基础 class 等中。理想情况下,您将拥有 XML 架构文件 (.xsd) 并且能够使用 xsd.exe
生成 classes,但这将适用于给定的 XML:
[XmlInclude(typeof(SubscriptionEvent))]
[XmlRoot(Namespace = "http://schema.broadsoft.com/xsi")]
public abstract class Event
{
}
[XmlType(Namespace = "http://schema.broadsoft.com/xsi")]
public class SubscriptionEvent : Event
{
[XmlElement(ElementName = "eventID")]
public string EventID { get; set; }
[XmlElement(ElementName = "sequenceNumber")]
public string SequenceNumber { get; set; }
[XmlElement(ElementName = "userId")]
public string UserId { get; set; }
[XmlElement(ElementName = "externalApplicationId")]
public string ExternalApplicationId { get; set; }
[XmlElement(ElementName = "subscriptionId")]
public string SubscriptionId { get; set; }
[XmlElement(ElementName = "channelId")]
public string ChannelId { get; set; }
[XmlElement(ElementName = "targetId")]
public string TargetId { get; set; }
[XmlElement(ElementName = "eventData")]
public EventData EventData { get; set; }
}
[XmlInclude(typeof(ACDSubscriptionEvent))]
public abstract class EventData
{
}
[XmlType(Namespace = "http://schema.broadsoft.com/xsi")]
public class ACDSubscriptionEvent : EventData
{
}
有关工作演示(使用 XmlSerializer
),请参阅 this fiddle。