繁体   English   中英

如何在 C# 中使用命名空间和 xml 类型解析 XML 属性

[英]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 typesxsi: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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM