[英]How to Parse XML Attribute with namespace and xml type in C#
我有以下要解析的 xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:IntegrationActionResponse xmlns:ns2="example.com">
<ActionResults>
<SuccessCount>1</SuccessCount>
<FailureCount>0</FailureCount>
<ActionResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:ParameterizedIntegrationActionResult">
<Status>OK</Status>
<resultParams>
<entry>
<key>abc</key>
<value>abc</value>
</entry>
<entry>
<key>abc</key>
<value>abc</value>
</entry>
<entry>
<key>abc</key>
<value>abc</value>
</entry>
</resultParams>
</ActionResult>
</ActionResults>
</ns2:IntegrationActionResponse>
我正在尝试使用此 model class 对其进行反序列化
using System.Collections.Generic;
using System.Xml.Serialization;
{
[XmlRoot(
IsNullable = false,
ElementName = "IntegrationActionResponse",
Namespace = "example.com"
)]
public class LoadIActionResponseModel
{
[XmlElement("ActionResults", Namespace = "")]
public LoadIActionResults ActionResults { get; set; }
}
public class LoadIActionResults
{
[XmlElement(ElementName = "SuccessCount")]
public int SuccessCount { get; set; }
[XmlElement(ElementName = "FailureCount")]
public int FailureCount { get; set; }
[XmlType(TypeName = "ParameterizedIntegrationActionResult", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public LoadIActionResult ActionResult { get; set; }
}
public class LoadIActionResult
{
[XmlElement(ElementName = "Status")]
public string Status { get; set; }
[XmlElement(ElementName = "resultParams")]
public LoadIActionResultParams resultParams {get; set;}
}
public class LoadIActionEntry
{
[XmlElement(ElementName = "key")]
public string Key { get; set; }
[XmlElement(ElementName = "value")]
public string Value { get; set; }
}
public class LoadIActionResultParams
{
[XmlElement(ElementName = "entry")]
public List<LoadIActionEntry> Entries { get; set; }
}
}
根节点正在反序列化。我尝试使用 XmlType 注释来解析属性,但 ActionResult 返回 null。 如何构建我的 model class 以接受 ActionResult 节点上的 xlmns 和 xsi 属性?
您的基本问题与Deserialize XML with multiple types和xsi:type 属性混淆 C# XML 反序列化的问题相同。 <ActionResult>
元素中存在xsi:type
类型属性:
<ActionResult xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:type=""ns2:ParameterizedIntegrationActionResult"">
<!--Contents omitted-->
</ActionResult>
指示此元素必须绑定到多态类型层次结构,其基类型对应于ActionResult
,子类型对应于ParameterizedIntegrationActionResult
。 But it seems as though you created your c# classes from your XML using some sort of automatic code generation tool such as the ones from Convert XML String to Object -- and unfortunately none of these tools is capable of automatically generating a polymorphic type hierarchy from an XML 样品。
因此,有必要手动修复您的数据 model,如下所示:
[XmlRoot(IsNullable = false,ElementName = "IntegrationActionResponse",Namespace = "example.com")]
public class LoadIActionResponseModel
{
[XmlElement("ActionResults", Namespace = "")]
public LoadIActionResults ActionResults { get; set; }
}
public class LoadIActionResults
{
[XmlElement(ElementName = "SuccessCount", Namespace = "")]
public int SuccessCount { get; set; }
[XmlElement(ElementName = "FailureCount", Namespace = "")]
public int FailureCount { get; set; }
[XmlElement(ElementName = "ActionResult", Namespace = "")] // Fixed
public ActionResultBase ActionResult { get; set; }
}
// Abstract base class added
[XmlType(TypeName="ActionResult", Namespace = "example.com")] // Fixed
[XmlInclude(typeof(ParameterizedIntegrationActionResult))] // Added
public abstract class ActionResultBase // Added
{
}
// LoadIActionResult renamed and made a subclass
[XmlType(TypeName="ParameterizedIntegrationActionResult", Namespace = "example.com")] // Fixed
public class ParameterizedIntegrationActionResult : ActionResultBase
{
[XmlElement(ElementName = "Status", Namespace = "")]
public string Status { get; set; }
[XmlElement(ElementName = "resultParams", Namespace = "")]
public LoadIActionResultParams resultParams {get; set;}
}
public class LoadIActionEntry
{
[XmlElement(ElementName = "key")]
public string Key { get; set; }
[XmlElement(ElementName = "value")]
public string Value { get; set; }
}
public class LoadIActionResultParams
{
[XmlElement(ElementName = "entry")]
public List<LoadIActionEntry> Entries { get; set; }
}
笔记:
对于要序列化的每个ActionResultBase
子类,您必须将[XmlInclude(typeof(TDerivedActionBase))]
添加到ActionResultBase
。
从 XML 显示,无法判断哪些属性应该属于ActionResultBase
哪些应该属于ParameterizedIntegrationActionResult
所以我将它们全部分配给派生类型。
您的代码还有一个错误:您尝试将XmlTypeAttribute
应用于ActionResult
:
[XmlType(TypeName = "ParameterizedIntegrationActionResult", Namespace = "http://www.w3.org/2001/XMLSchema-instance")] public LoadIActionResult ActionResult { get; set; }
但是,此属性只能应用于 class、结构、枚举或接口。 您应该改用XmlElementAttribute
。
While no .NET code generation tool with which I am familiar will generate a polymorphic type hierarchy from an XML sample, some such as xsd.exe
will generate one correctly from an XSD schema. 如果你有一个模式,你应该从它而不是从 XML 生成你的类。
演示小提琴在这里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.