c# – 如何使用注释从类的属性值派生xml元素名称?

c# – 如何使用注释从类的属性值派生xml元素名称?,第1张

概述我有 具有ID和值以及名称的属性.我可以使用XmlElement / XmlArray C#注释代表所有具有单个类的人吗?我想从类属性名称派生xml元素名称; 我的课看起来像: public class Property { public string name; //could be enum public int id; public string value;} 例如: @H_404_6@ 我有
具有ID和值以及名称的属性.我可以使用XmlElement / XmlArray C#注释代表所有具有单个类的人吗?我想从类属性名称派生xml元素名称;

我的课看起来像:

public class Property {   public string name; //Could be enum   public int ID;    public string value;}

例如:

new Property("property1name",2,"testvalue");new Property("property2name",10,"anothervalue");

我想要xml看起来像:

<property1name><ID>2</ID><value>testvalue</value></property1name><property2name><ID>10</ID><value>anothervalue</value></property2name>

而不是通常的

<property><name>property1name</name><ID>2</ID><value>testvalue</value></property><property><name>property2name</name><ID>10</ID><value>anothervalue</value></property>

换句话说,xmlelement从类Property的属性名称中获取其名称

解决方法 更新

这是一个快速适应处理您的Property类.首先,列表< T>实现IXmlSerializable的子类:

public interface IHasElementname{    string Elementname { get; set; }}public class XmlnamedElementList<T> : List<T>,IXmlSerializable where T : IHasXmlElementname{    // https://msdn.microsoft.com/en-us/library/System.Xml.Serialization.XmlSerializer%28v=vs.110%29.aspx    // Any serializer created with the "XmlSerializer(typeof(T),rootAttribute)" must be cached    // to avoID resource & memory leaks.    class ValueSerializerCache    {        // By using a nested class with a static constructor,we defer generation of the XmlSerializer until it's actually required.        static ValueSerializerCache()        {            var rootAttribute = new XmlRootAttribute();            rootAttribute.Elementname = ValueTypename;            rootAttribute.namespace = ValueTypenamespace;            serializer = new XmlSerializer(typeof(T),rootAttribute);        }        static Readonly XmlSerializer serializer;        internal static XmlSerializer Serializer { get { return serializer; } }    }    static string ValueTypename { get { return typeof(T).DefaultXmlElementname(); } }    static string ValueTypenamespace { get { return typeof(T).DefaultXmlElementnamespace(); } }    #region IXmlSerializable Members    XmlSchema IXmlSerializable.GetSchema()    {        return null;    }    voID IXmlSerializable.readxml(XmlReader reader)    {        if (reader.IsEmptyElement)        {            reader.Read();            return;        }        var typename = ValueTypename;        reader.ReadStartElement(); // Advance to the first sub element of the List element.        while (reader.NodeType == XmlNodeType.Element)        {            var name = reader.name;            using (var subReader = reader.ReadSubtree())            {                var doc = Xdocument.Load(subReader);                if (doc != null && doc.Root != null)                {                    doc.Root.name = doc.Root.name.namespace + typename;                    using (var docReader = doc.CreateReader())                    {                        var obj = ValueSerializerCache.Serializer.Deserialize(docReader);                        if (obj != null)                        {                            T value = (T)obj;                            value.Elementname = XmlConvert.Decodename(name);                            Add(value);                        }                    }                }            }            // Move past the end of item element            reader.Read();        }        // Move past the end of the List element        reader.ReadEndElement();    }    voID IXmlSerializable.WriteXml(XmlWriter writer)    {        foreach (var value in this)        {            Xdocument doc = new Xdocument();            using (var subWriter = doc.CreateWriter())            {                // write xml into the writer                ValueSerializerCache.Serializer.Serialize(subWriter,value);            }            if (doc.Root == null)                continue;            doc.Root.name = doc.Root.name.namespace + XmlConvert.Encodename(value.Elementname);            // Remove redundant namespaces.            foreach (var attr in doc.Root.Attributes().ToList())            {                if (!attr.IsnamespaceDeclaration || string.IsNullOrEmpty(attr.Value))                    continue;                var prefix = writer.LookupPrefix(attr.Value);                if ((prefix == attr.name.Localname)                    || (prefix == string.Empty && attr.name == "xmlns"))                    attr.Remove();            }            doc.Root.Writeto(writer);        }    }    #endregion}public static class XmlSerializationHelper{    static Attribute GetCustomAttribute(MemberInfo element,Type attributeType)    {        return Attribute.GetCustomAttribute(element,attributeType);    }    static T GetCustomAttribute<T>(MemberInfo element) where T : Attribute    {        return (T)GetCustomAttribute(element,typeof(T));    }    public static string DefaultXmlElementname(this Type type)    {        var xmlType = GetCustomAttribute<XmlTypeAttribute>(type);        if (xmlType != null && !string.IsNullOrEmpty(xmlType.Typename))            return xmlType.Typename;        var xmlRoot = GetCustomAttribute<XmlRootAttribute>(type);        if (xmlRoot != null && !string.IsNullOrEmpty(xmlRoot.Elementname))            return xmlRoot.Elementname;        return type.name;    }    public static string DefaultXmlElementnamespace(this Type type)    {        var xmlType = GetCustomAttribute<XmlTypeAttribute>(type);        if (xmlType != null && !string.IsNullOrEmpty(xmlType.namespace))            return xmlType.namespace;        var xmlRoot = GetCustomAttribute<XmlRootAttribute>(type);        if (xmlRoot != null && !string.IsNullOrEmpty(xmlRoot.namespace))            return xmlRoot.namespace;        return string.Empty;    }    public static string GetXml<T>(this T obj)    {        return GetXml(obj,false);    }    public static string GetXml<T>(this T obj,bool omitnamespace)    {        return GetXml(obj,new XmlSerializer(obj.GetType()),omitnamespace);    }    public static string GetXml<T>(this T obj,XmlSerializer serializer)    {        return GetXml(obj,serializer,false);    }    public static string GetXml<T>(T obj,XmlSerializer serializer,bool omitStandardnamespaces)    {        XmlSerializernamespaces ns = null;        if (omitStandardnamespaces)        {            ns = new XmlSerializernamespaces();            ns.Add("",""); // disable the xmlns:xsi and xmlns:xsd lines.        }        return GetXml(obj,ns);    }    public static string GetXml<T>(T obj,XmlSerializernamespaces ns)    {        return GetXml(obj,XmlSerializernamespaces ns)    {        using (var textWriter = new StringWriter())        {            XmlWriterSettings settings = new XmlWriterSettings();            settings.Indent = true;        // For cosmetic purposes.            settings.IndentChars = "    "; // For cosmetic purposes.            using (var xmlWriter = XmlWriter.Create(textWriter,settings))            {                if (ns != null)                    serializer.Serialize(xmlWriter,obj,ns);                else                    serializer.Serialize(xmlWriter,obj);            }            return textWriter.ToString();        }    }}

并使用它像:

public class Property : IHasElementname{    public property()    {    }    public Property(string name,int ID,string value)    {        this.name = name;        this.ID = ID;        this.value = value;    }    [Xmlignore]    public string name; //Could be enum    public int ID;    public string value;    #region IHasElementname Members    [Xmlignore]    string IHasElementname.Elementname { get { return name; }  set { name = value; } }    #endregion}public class RootObject{    public RootObject()    {        this.PropertIEs = new XmlnamedElementList<Property>();    }    public XmlnamedElementList<Property> PropertIEs { get; set; }}public static class TestClass{    public static voID test()    {        var root = new RootObject        {            // Characters " <> first" in the first element name are for testing purposes.            PropertIEs = new XmlnamedElementList<Property> { new Property { ID = 1,value = "1",name = "first" },new Property("property1name","testvalue"),new Property("property2name","anothervalue") }        };        var xml = root.GetXml();        DeBUG.Writeline(xml);    }}

其中生成XML如下:

<?xml version="1.0" enCoding="utf-16"?><RootObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">    <PropertIEs>        <_x0020__x003C__x003E__x0020_first>            <ID>1</ID>            <value>1</value>        </_x0020__x003C__x003E__x0020_first>        <property1name>            <ID>2</ID>            <value>testvalue</value>        </property1name>        <property2name>            <ID>10</ID>            <value>anothervalue</value>        </property2name>    </PropertIEs></RootObject>

原始答案

根据要求,这是List< keyvaluePair< string,T>>上IXmlSerializable的实现.其中Key字符串成为集合中的元素名称.

您可能想要做的是调整它以序列化List< IHasElementname>哪里:

public interface IHasElementname{    string Elementname { get; set; }}public class Property : IHasElementname{    [Xmlignore]    public string name; //Could be enum    public int ID;    public string value;    #region IHasElementname Members    [Xmlignore]    string IHasElementname.Elementname    {        get        {            return name;        }        set        {            name = value;        }    }    #endregion}

如果名称实际上是Enum,则可以从HasElementname.Elementname返回枚举字符串表示形式.

该列表如下:

public class XmlkeyvalueList<T> : List<keyvaluePair<string,T>>,IXmlSerializable{    // Todo: valIDate that the "Key" string using XmlConvert.Verifyname.    // https://msdn.microsoft.com/en-us/library/System.Xml.Serialization.XmlSerializer%28v=vs.110%29.aspx    // Any serializer created with the "XmlSerializer(typeof(T),rootAttribute);        }        static Readonly XmlSerializer serializer;        internal static XmlSerializer Serializer { get { return serializer; } }    }    static string ValueTypename { get { return typeof(T).DefaultXmlElementname(); } }    static string ValueTypenamespace { get { return typeof(T).DefaultXmlElementnamespace(); } }    #region IXmlSerializable Members    XmlSchema IXmlSerializable.GetSchema()    {        return null;    }    voID IXmlSerializable.readxml(XmlReader reader)    {        var typename = ValueTypename;        reader.ReadStartElement(); // Advance to the first sub element of the List element.        while (reader.NodeType == XmlNodeType.Element)        {            var name = reader.name;            using (var subReader = reader.ReadSubtree())            {                var doc = Xdocument.Load(subReader);                if (doc != null && doc.Root != null)                {                    doc.Root.name = typename;                    using (var docReader = doc.CreateReader())                    {                        var obj = ValueSerializerCache.Serializer.Deserialize(docReader);                        if (obj != null)                        {                            Add(new keyvaluePair<string,T>(name,(T)obj));                        }                    }                }            }            // Move past the XmlNodeType.Element            if (reader.NodeType == XmlNodeType.EndElement)                reader.Read();        }    }    voID IXmlSerializable.WriteXml(XmlWriter writer)    {        foreach (var pair in this)        {            Xdocument doc = new Xdocument();            using (var subWriter = doc.CreateWriter())            {                // write xml into the writer                ValueSerializerCache.Serializer.Serialize(subWriter,pair.Value);            }            if (doc.Root == null)                continue;            doc.Root.name = pair.Key;            // Remove redundant namespaces.            foreach (var attr in doc.Root.Attributes().ToList())            {                if (!attr.IsnamespaceDeclaration || string.IsNullOrEmpty(attr.Value))                    continue;                if (writer.LookupPrefix(attr.Value) == attr.name.Localname)                    attr.Remove();            }            doc.Root.Writeto(writer);        }    }    #endregion}public static class XmlSerializationHelper{    public static string DefaultXmlElementname(this Type type)    {        var xmlType = type.GetCustomAttribute<XmlTypeAttribute>();        if (xmlType != null && !string.IsNullOrEmpty(xmlType.Typename))            return xmlType.Typename;        var xmlRoot = type.GetCustomAttribute<XmlRootAttribute>();        if (xmlRoot != null && !string.IsNullOrEmpty(xmlRoot.Elementname))            return xmlRoot.Elementname;        return type.name;    }    public static string DefaultXmlElementnamespace(this Type type)    {        var xmlType = type.GetCustomAttribute<XmlTypeAttribute>();        if (xmlType != null && !string.IsNullOrEmpty(xmlType.namespace))            return xmlType.namespace;        var xmlRoot = type.GetCustomAttribute<XmlRootAttribute>();        if (xmlRoot != null && !string.IsNullOrEmpty(xmlRoot.namespace))            return xmlRoot.namespace;        return string.Empty;    }}
总结

以上是内存溢出为你收集整理的c# – 如何使用注释从类的属性值派生xml元素名称?全部内容,希望文章能够帮你解决c# – 如何使用注释从类的属性值派生xml元素名称?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1226732.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存