元素类型 dt:dt 命名空间的 XmlSerializer 属性命名空间 [英] XmlSerializer attribute namespace for element type dt:dt namespace

查看:44
本文介绍了元素类型 dt:dt 命名空间的 XmlSerializer 属性命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找 XmlSerializer 功能来在我的输出 XML 中重新创建一些命名空间/类型信息.

所以我必须将这样的 XML 输出复制到旧的 COM 应用程序:

500<StartTime dt:dt="dateTime">2014-12-30T12:00:00.000</StartTime>

我目前像这样设置我的属性的属性:

[XmlElement(ElementName = "Amount", Namespace = "urn:schemas-microsoft-com:datatypes",DataType = "int", Type = typeof(int))]公共整数金额{得到;放;}

我的 XmlSerializer 和命名空间设置如下:

XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();namespaces.Add("dt", "urn:schemas-microsoft-com:datatypes");s.Serialize(writer, group, namespaces);

但这只会给我这样的输出:

500

有人知道我哪里出错了吗?

解决方案

XmlElementAttribute.Namespace 指定元素本身的命名空间,而不是元素的属性.这就是您看到 dt: 前缀的原因.和 DataType = "int" 在这里没有帮助;它用于指定多态字段的类型,不会自动生成 dt 数据类型属性.实际上,XmlSerializer 中没有内置功能来自动生成 XDR 数据类型属性值,属于命名空间 "urn:schemas-microsoft-com:datatypes".

因此,有必要使用具有必要属性的包装器结构手动执行此操作.以下实现是类型化的而不是多态的:

public struct XdrTypeWrapper;{类 XdrTypeWrapperTypeDictionary{静态 XdrTypeWrapperTypeDictionary 实例;static XdrTypeWrapperTypeDictionary() { instance = new XdrTypeWrapper.XdrTypeWrapperTypeDictionary();}公共静态 XdrTypeWrapperTypeDictionary 实例 { 获取 { 返回实例;} }只读字典<类型,字符串>字典;XdrTypeWrapperTypeDictionary(){//取自 https://msdn.microsoft.com/en-us/library/ms256121.aspx//https://msdn.microsoft.com/en-us/library/ms256049.aspx//https://msdn.microsoft.com/en-us/library/ms256088.aspxdict = 新字典<类型,字符串>{{ typeof(string), "string" },{ typeof(sbyte), "i1" },{ typeof(byte), "u1" },{ typeof(short), "i2" },{ typeof(ushort), "u2" },{ typeof(int), "int" },//可以使用 i4{ typeof(uint), "ui4" },{ typeof(long), "i8" },{ typeof(ulong), "ui8" },{ typeof(DateTime), "dateTime" },{ typeof(bool), "boolean" },{ typeof(double), "float" },//可以使用 r8{ typeof(float), "r4" },};}公共字符串数据类型(类型类型){返回字典[类型];}}public XdrTypeWrapper(T value) { this.value = value;}公共静态隐式运算符 XdrTypeWrapper(T value) { return new XdrTypeWrapper(value);}公共静态隐式运算符 T(XdrTypeWrapper wrapper) { return wrapper.Value;}[XmlAttribute("dt", Namespace = "urn:schemas-microsoft-com:datatypes")]公共字符串数据类型{得到{返回 XdrTypeWrapperTypeDictionary.Instance.DataType(typeof(T));}放{//没做什么.}}T值;[XML文本]公共 T 值 { 获取 { 返回值;} set { this.value = value;} }}

然后在具有代理属性的类中使用它,如下所示:

公共类TestClass{[XmlIgnore]公共整数金额{得到;放;}[XmlElement("金额")][Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]公共 XdrTypeWrapper;XmlAmount { 获取 { 返回金额;} 设置 { 金额 = 值;} }[XmlIgnore]公共日期时间开始时间{获取;放;}[XmlElement("StartTime")][Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]public XdrTypeWrapperXmlStartTime { get { return StartTime; }} 设置 { 开始时间 = 值;} }[XmlIgnore]公共双双{得到;放;}[XmlElement("双")][Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]public XdrTypeWrapper;XmlDouble { 得到 { 返回双;} 设置 { 双 = 值;} }}

生成以下 XML:

<块引用>

<Amount dt:dt="int">101</Amount><StartTime dt:dt="dateTime">2015-10-06T20:35:18.2308848+00:00</StartTime><Double dt:dt="float">101.23</Double></TestClass>

原型 fiddle.

I'm looking for the XmlSerializer functionality to re-create some namespace/type info in my output XML.

So I have to replicate XML output like this to an old COM application:

<Amount dt:dt="int">500</Amount>  
<StartTime dt:dt="dateTime">2014-12-30T12:00:00.000</StartTime>      

I currently set the attributes of my properties like so:

[XmlElement(ElementName = "Amount", Namespace = "urn:schemas-microsoft-com:datatypes",  
DataType = "int", Type = typeof(int))]  
public int Amount{ get; set; }  

With my XmlSerializer and Namespaces set like this:

XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("dt", "urn:schemas-microsoft-com:datatypes");
s.Serialize(writer, group, namespaces);

But this only gives me output like:

<dt:Amount>500</dt:Amount> 

Anyone have an idea where I'm going wrong?

解决方案

The XmlElementAttribute.Namespace specifies the namespace of the element itself, not an attribute of the element. That's why you are seeing the dt: prefix. And the DataType = "int" isn't helping you here; it's for specifying the type of polymorphic fields, and won't auto-generate a dt data type attribute. In fact, there's no built-in functionality in XmlSerializer to auto-generate an XDR data type attribute values, which belong in the namespace "urn:schemas-microsoft-com:datatypes".

Thus, it's necessary to do it manually, using a wrapper struct with the necessary attribute. The following implementation is typed rather than polymorphic:

public struct XdrTypeWrapper<T>
{
    class XdrTypeWrapperTypeDictionary
    {
        static XdrTypeWrapperTypeDictionary instance;

        static XdrTypeWrapperTypeDictionary() { instance = new XdrTypeWrapper<T>.XdrTypeWrapperTypeDictionary(); }

        public static XdrTypeWrapperTypeDictionary Instance { get { return instance; } }

        readonly Dictionary<Type, string> dict;

        XdrTypeWrapperTypeDictionary()
        {
            // Taken from https://msdn.microsoft.com/en-us/library/ms256121.aspx
            // https://msdn.microsoft.com/en-us/library/ms256049.aspx
            // https://msdn.microsoft.com/en-us/library/ms256088.aspx
            dict = new Dictionary<Type, string>
            {
                { typeof(string), "string" },
                { typeof(sbyte), "i1" },
                { typeof(byte), "u1" },
                { typeof(short), "i2" },
                { typeof(ushort), "u2" },
                { typeof(int), "int" }, // Could have used i4
                { typeof(uint), "ui4" },
                { typeof(long), "i8" },
                { typeof(ulong), "ui8" },
                { typeof(DateTime), "dateTime" },
                { typeof(bool), "boolean" },
                { typeof(double), "float" }, // Could have used r8
                { typeof(float), "r4" },
            };
        }

        public string DataType(Type type)
        {
            return dict[type];
        }
    }

    public XdrTypeWrapper(T value) { this.value = value; }

    public static implicit operator XdrTypeWrapper<T>(T value) { return new XdrTypeWrapper<T>(value); }

    public static implicit operator T(XdrTypeWrapper<T> wrapper) { return wrapper.Value; }

    [XmlAttribute("dt", Namespace = "urn:schemas-microsoft-com:datatypes")]
    public string DataType
    {
        get
        {
            return XdrTypeWrapperTypeDictionary.Instance.DataType(typeof(T));
        }
        set
        {
            // Do nothing.
        }
    }

    T value;

    [XmlText]
    public T Value { get { return value; } set { this.value = value; } }
}

Then use it in your classes with proxy properties as follows:

public class TestClass
{
    [XmlIgnore]
    public int Amount { get; set; }

    [XmlElement("Amount")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public XdrTypeWrapper<int> XmlAmount { get { return Amount; } set { Amount = value; } }

    [XmlIgnore]
    public DateTime StartTime { get; set; }

    [XmlElement("StartTime")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public XdrTypeWrapper<DateTime> XmlStartTime { get { return StartTime; } set { StartTime = value; } }

    [XmlIgnore]
    public double Double { get; set; }

    [XmlElement("Double")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public XdrTypeWrapper<double> XmlDouble { get { return Double; } set { Double = value; } }
}

Which produces the following XML:

<TestClass xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <Amount dt:dt="int">101</Amount>
  <StartTime dt:dt="dateTime">2015-10-06T20:35:18.2308848+00:00</StartTime>
  <Double dt:dt="float">101.23</Double>
</TestClass>

Prototype fiddle.

这篇关于元素类型 dt:dt 命名空间的 XmlSerializer 属性命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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