元素类型 dt:dt 命名空间的 XmlSerializer 属性命名空间 [英] XmlSerializer attribute namespace for element type dt:dt namespace
问题描述
我正在寻找 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屋!