如何将XML元素反序列化为具有未知元素名称的通用列表 [英] How to Deserialize XML elements to generic list with unknown element names

查看:148
本文介绍了如何将XML元素反序列化为具有未知元素名称的通用列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



XML如下所示:

 <详细> 
< DetailAttributes>
<名称>名称123< /名称>
<类型> Type_123< / Type>
< / DetailAttributes>
<其他属性>
< SummaryKey AttributeName =SummaryKey> SummaryKey_123< / SummaryKey>
< Account AttributeName =Account> Account_123< / Account>
< / OtherAttributes>
< /详细>

我没有任何反序列化'Name'和'Type'元素的问题,我可以反序列化'SummaryKey '和'Account'元素,但前提是明确指定了他们的元素名称 - 这不是所需的方法,因为'OtherAttributes'可能会发生变化。

我的类是如下所示:

  [XmlRoot(Detail)] 
public class objectDetailsList
{
[XmlElement(DetailAttributes),Type = typeof(DetailAttribute))]
public DetailAttribute [] detailAttributes {get;组; }

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

public objectDetailsList()
{
}
}
[可序列化]
公共类详细属性
{
[XmlElement(Type)]
public string Type {get; set; }

[XmlElement(Name)]
public string Name {get; set; }
$ b $ public DetailAttribute()
{
}
}

[可序列化]
公共类OtherAttribute
{
//以下将反序列化

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

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

//我想在下面做的是创建一个没有已知名称的所有'其他属性'列表

[XmlArray(OtherAttributes)]
公开列表< Element>元素{get;组; }}



$ b $ {
[XmlAttribute(AttributeName)]
[XmlRoot(OtherAttributes)]
public class Element公共字符串aName {get;组; }

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

当我尝试检索OtherAttribute元素的反序列化列表时,count为零所以它无法访问嵌套在其他属性中的元素。



任何人都可以帮我解决这个问题吗?

解决方案

类和动态数据,你将无法依靠标准的XmlSerializer来为你序列化/反序列化 - 因为它反映了你的类,而你想要填充的属性根本不存在。如果你的一套'OtherAttributes'是已知的且有限的,并且不受未来改变的影响,你可以为所有可能的属性提供一个类,但是这会给你一个丑陋的臃肿课程(我认为你已经认定这不是解决方案)。



实用选项因此:


  • 。使用XmlDocument类,使用.Load()加载数据,并使用XPath查询(类似于/ Detail / OtherAttributes / *)使用.SelectNodes()来迭代节点。您必须自己编写批次,但是这可以让您完全控制序列化/反序列化。你不需要在(可以说是多余的!)属性中覆盖你的代码。

  • 使用Json.NET( http://james.newtonking.com/json ),它可以更好地控制序列化和反序列化。它很快,有很好的文档,真的很漂亮。

I am retrieving and successfully deserializing an xml string from a database table column for the known element names (these do not change) but there are also some nested XML Elements called "Other Attributes" which are not always going to be known. I'm having some trouble deserialising these unknown element names to a generic list so I can display them in html once deserialised.

The XML is as follows:

<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>

I have no problem deserialising the 'Name' and 'Type' elements and I can deserialise the 'SummaryKey' and 'Account' elements but only if I explicitly specify their element names - which is not the desired approach because the 'OtherAttributes' are subject to change.

My classes are as follows:

[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; }
}

When I try to retrieve the deserialised list of OtherAttribute elements the count is zero so it's not able to access the elements nested within "Other Attributes".

Can anybody help me with this please?

解决方案

With concrete classes and dynamic data like this, you won't be able to lean on the standard XmlSerializer to serialize / deserialize for you - as it reflects on your classes, and the properties you want to populate simply don't exist. You could provide a class with all possible properties if your set of 'OtherAttributes' is known and finite, and not subject to future change, but that would give you an ugly bloated class (and I think you've already decided this is not the solution).

Practical options therefore:

  • Do it manually. Use the XmlDocument class, load your data with .Load(), and iterate the nodes using .SelectNodes() using an XPath query (something like "/Detail/OtherAttributes/*"). You will have to write the lot yourself, but this gives you complete control over the serialization / deserialization. You won't have to cover your code in (arguably superfluous!) attributes either.

  • Use Json.NET (http://james.newtonking.com/json), it allows for far greater control over serialization and deserialization. It's fast, has good docs and is overall pretty nifty really.

这篇关于如何将XML元素反序列化为具有未知元素名称的通用列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆