C# 如何将XML元素反序列化为具有未知元素名称的通用列表

C# 如何将XML元素反序列化为具有未知元素名称的通用列表,c#,xml,generics,C#,Xml,Generics,我正在从数据库表列中检索并成功地反序列化一个xml字符串,以获取已知的元素名称(这些名称不会更改),但也有一些称为“其他属性”的嵌套xml元素,它们并不总是已知的。我在将这些未知元素名称反序列化到通用列表时遇到了一些问题,以便反序列化后可以在html中显示它们 XML如下所示: <Detail> <DetailAttributes> <Name>Name_123</Name> <Type>Type_123</Type> &l

我正在从数据库表列中检索并成功地反序列化一个xml字符串,以获取已知的元素名称(这些名称不会更改),但也有一些称为“其他属性”的嵌套xml元素,它们并不总是已知的。我在将这些未知元素名称反序列化到通用列表时遇到了一些问题,以便反序列化后可以在html中显示它们

XML如下所示:

<Detail>
<DetailAttributes>
<Name>Name_123</Name>
<Type>Type_123</Type>
</DetailAttributes>
<OtherAttributes>
<SummaryKey AttributeName="SummaryKey">SummaryKey_123</SummaryKey>
<Account AttributeName="Account">Account_123</Account>
</OtherAttributes>
</Detail>
[XmlRoot("Detail")]
public class objectDetailsList
{
    [XmlElement("DetailAttributes"), Type = typeof(DetailAttribute))]
    public DetailAttribute[] detailAttributes { get; set; }

    [XmlElement("OtherAttributes")]
    public List<OtherAttribute> otherAttributes { get; set; }

    public objectDetailsList()
    {
    }
}
[Serializable]
public class Detail Attribute
{
    [XmlElement("Type")]
    public string Type { get;set; }

    [XmlElement("Name")]
    public string Name { get;set; }

    public DetailAttribute()
    {
    }
}

[Serializable]
public class OtherAttribute
{
    //The following will deserialise ok

    //[XmlElement("SummaryKey")]
    //public string sumKey { get; set; }

    //[XmlElement("Account")]
    //public string acc { get; set; }

    //What I want to do below is create a list of all 'other attributes' without known names

    [XmlArray("OtherAttributes")]
    public List<Element> element { get; set; }
}

[XmlRoot("OtherAttributes")]
public class Element
{
    [XmlAttribute("AttributeName")]
    public string aName { get; set; }

    [XmlText]
    public string aValue { get; set; }
}

姓名(u 123)
第123类
总结键123
账户123
反序列化'Name'和'Type'元素没有问题,而且我可以反序列化'SummaryKey'和'Account'元素,但前提是我明确指定它们的元素名称,这不是理想的方法,因为'OtherAttributes'可能会更改

我的课程如下:

<Detail>
<DetailAttributes>
<Name>Name_123</Name>
<Type>Type_123</Type>
</DetailAttributes>
<OtherAttributes>
<SummaryKey AttributeName="SummaryKey">SummaryKey_123</SummaryKey>
<Account AttributeName="Account">Account_123</Account>
</OtherAttributes>
</Detail>
[XmlRoot("Detail")]
public class objectDetailsList
{
    [XmlElement("DetailAttributes"), Type = typeof(DetailAttribute))]
    public DetailAttribute[] detailAttributes { get; set; }

    [XmlElement("OtherAttributes")]
    public List<OtherAttribute> otherAttributes { get; set; }

    public objectDetailsList()
    {
    }
}
[Serializable]
public class Detail Attribute
{
    [XmlElement("Type")]
    public string Type { get;set; }

    [XmlElement("Name")]
    public string Name { get;set; }

    public DetailAttribute()
    {
    }
}

[Serializable]
public class OtherAttribute
{
    //The following will deserialise ok

    //[XmlElement("SummaryKey")]
    //public string sumKey { get; set; }

    //[XmlElement("Account")]
    //public string acc { get; set; }

    //What I want to do below is create a list of all 'other attributes' without known names

    [XmlArray("OtherAttributes")]
    public List<Element> element { get; set; }
}

[XmlRoot("OtherAttributes")]
public class Element
{
    [XmlAttribute("AttributeName")]
    public string aName { get; set; }

    [XmlText]
    public string aValue { get; set; }
}
[XmlRoot(“细节”)]
公共类objectDetailsList
{
[xmlement(“DetailAttributes”),Type=typeof(DetailAttribute))]
public DetailAttribute[]detailAttributes{get;set;}
[XmlElement(“其他属性”)]
公共列表其他属性{get;set;}
公共对象详细信息列表()
{
}
}
[可序列化]
公共类详细信息属性
{
[XmlElement(“类型”)]
公共字符串类型{get;set;}
[XmlElement(“名称”)]
公共字符串名称{get;set;}
公共详细信息属性()
{
}
}
[可序列化]
公共类OtherAttribute
{
//下面将反序列化ok
//[XmlElement(“SummaryKey”)]
//公共字符串sumKey{get;set;}
//[XmlElement(“账户”)]
//公共字符串acc{get;set;}
//下面我想做的是创建一个没有已知名称的所有“其他属性”的列表
[XmlArray(“其他属性”)]
公共列表元素{get;set;}
}
[XmlRoot(“其他属性”)]
公共类元素
{
[XmlAttribute(“AttributeName”)]
公共字符串aName{get;set;}
[XmlText]
公共字符串aValue{get;set;}
}
当我尝试检索OtherAttribute元素的反序列化列表时,计数为零,因此无法访问嵌套在“Other Attributes”中的元素


有人能帮我吗?

对于这样的具体类和动态数据,您将无法依靠标准XmlSerializer进行序列化/反序列化-因为它反映在您的类上,并且您想要填充的属性根本不存在。如果您的“OtherAttributes”集合是已知的且有限的,并且不受未来更改的影响,那么您可以提供一个包含所有可能属性的类,但这会给您带来一个丑陋的臃肿类(我认为您已经决定这不是解决方案)

因此,切实可行的选择:

  • 手动操作。使用XmlDocument类,使用.load()加载数据,并使用XPath查询(类似“/Detail/OtherAttributes/*”)使用.SelectNodes()迭代节点。您必须自己编写批,但这使您能够完全控制序列化/反序列化。您也不必在属性中覆盖代码(可以说是多余的!)

  • 使用Json.NET(),它允许对序列化和反序列化进行更大的控制。它的速度很快,有很好的文档,而且总体上非常漂亮


我最初选择了xsd.exe路径,但实际上毫无用处。所以我按照您的建议使用了XmlDocument类,效果非常好-非常感谢!