简体   繁体   English

元素类型dt:dt命名空间的XmlSerializer属性命名空间

[英]XmlSerializer attribute namespace for element type dt:dt namespace

I'm looking for the XmlSerializer functionality to re-create some namespace/type info in my output XML. 我正在寻找XmlSerializer功能以在输出XML中重新创建一些名称空间/类型信息。

So I have to replicate XML output like this to an old COM application: 因此,我必须将这样的XML输出复制到旧的COM应用程序中:

<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: 将我的XmlSerializer和命名空间设置如下:

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. XmlElementAttribute.Namespace指定元素本身的名称空间,而不是元素的属性。 That's why you are seeing the dt: prefix. 这就是为什么您看到dt:前缀的原因。 And the DataType = "int" isn't helping you here; 而且DataType = "int"在这里没有帮助您; it's for specifying the type of polymorphic fields, and won't auto-generate a dt data type attribute . 它用于指定多态字段的类型,并且不会自动生成dt 数据类型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" . 实际上, XmlSerializer没有内置功能来自动生成XDR数据类型属性值 ,这些属于命名空间"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: 产生以下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 . 原型摆弄

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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