如何添加XmlInclude动态属性 [英] How to add XmlInclude attribute dynamically

查看:1012
本文介绍了如何添加XmlInclude动态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类

[XmlRoot]
public class AList
{
   public List<B> ListOfBs {get; set;}
}

public class B
{
   public string BaseProperty {get; set;}
}

public class C : B
{
    public string SomeProperty {get; set;}
}

public class Main
{
    public static void Main(string[] args)
    {
        var aList = new AList();
        aList.ListOfBs = new List<B>();
        var c = new C { BaseProperty = "Base", SomeProperty = "Some" };
        aList.ListOfBs.Add(c);

        var type = typeof (AList);
        var serializer = new XmlSerializer(type);
        TextWriter w = new StringWriter();
        serializer.Serialize(w, aList);
    }    
}

现在,当我尝试运行code我得到了一个InvalidOperationException在最后一行说,

Now when I try to run the code I got an InvalidOperationException at last line saying that

类型XmlTest.C是没有预料到。使用XmlInclude或SoapInclude属性来指定不知道静态类型。

The type XmlTest.C was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

我知道,添加一个[XmlInclude(typeof运算(C))]属性与[XmlRoot]会解决这个问题。但我想动态实现它。因为在我的项目C类是没有在装船前已知的。 C类被装载作为插件,因此它不可能我补充XmlInclude属性有

I know that adding a [XmlInclude(typeof(C))] attribute with [XmlRoot] would solve the problem. But I want to achieve it dynamically. Because in my project class C is not known prior to loading. Class C is being loaded as a plugin, so it is not possible for me to add XmlInclude attribute there.

我也试过用

TypeDescriptor.AddAttributes(typeof(AList), new[] { new XmlIncludeAttribute(c.GetType()) });

var type = typeof (AList);

但没有用。它仍然给了同样的异常。

but no use. It is still giving the same exception.

没有任何一个有关于如何实现呢?任何想法

Does any one have any idea on how to achieve it?

推荐答案

两个选项;最简单的(但给奇XML)是:

Two options; the simplest (but giving odd xml) is:

XmlSerializer ser = new XmlSerializer(typeof(AList),
    new Type[] {typeof(B), typeof(C)});

使用示例输出:

<AList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ListOfBs>
    <B />
    <B xsi:type="C" />
  </ListOfBs>
</AList>

更优雅是:

XmlAttributeOverrides aor = new XmlAttributeOverrides();
XmlAttributes listAttribs = new XmlAttributes();
listAttribs.XmlElements.Add(new XmlElementAttribute("b", typeof(B)));
listAttribs.XmlElements.Add(new XmlElementAttribute("c", typeof(C)));
aor.Add(typeof(AList), "ListOfBs", listAttribs);

XmlSerializer ser = new XmlSerializer(typeof(AList), aor);

使用示例输出:

<AList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <b />
  <c />
</AList>

在您必须缓存和重新使用例如这两种情况下,否则,你会从动态编译大出血内存。

In either case you must cache and re-use the ser instance; otherwise you will haemorrhage memory from dynamic compilation.

这篇关于如何添加XmlInclude动态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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