How to add attributes for C# XML Serialization

前端 未结 4 1913
心在旅途
心在旅途 2020-11-30 03:42

I am having an issue with serializing and object, I can get it to create all the correct outputs except for where i have an Element that needs a value and an attribute. Here

相关标签:
4条回答
  • 2020-11-30 04:10

    It sounds like you need an extra class:

    public class Document
    {
        [XmlAttribute("type")]
        public string Type { get; set; }
        [XmlText]
        public string Name { get; set; }
    }
    

    Where an instance (in the example) would have Type = "word" and Name = "document name"; documents would be a List<Document>.

    By the way - public fields are rarely a good idea...

    0 讨论(0)
  • 2020-11-30 04:10

    You can use XmlWriter instead XmlSerialization to get this effect. It is more complex but if you have a lot of strings in model it will be cleaner solution.

    Create your own CustomeAttribute, for example:

    [System.AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class MyCustomAttribute : System.Attribute
    {
        public MyCustomAttribute (string type)
        {
            MyType = type;
        }
        public string MyType { get; set; }
    }
    

    Then in model add it, like that:

    public class MyModel
    {
        [MyCustom("word")]
        public string Document { get; set; }
        [MyCustom("time")]
        public string Time { get; set; }
    }
    

    The last part is to create xml with this arguments. You can do it likes that:

            var doc = new XmlDocument();
            MyModel myModel = new MyModel();//or get it from somewhere else
            using (Stream s = new MemoryStream())
            {
                var settings = new XmlWriterSettings();
                settings.Async = true;
                settings.Indent = true;
                var writer = XmlTextWriter.Create(s, settings);
                await writer.WriteStartDocumentAsync();
                await writer.WriteStartElementAsync(null,"Root", null);
    
                myModel.GetType().GetProperties().ToList().ForEach(async p =>
                {
                    dynamic value = p.GetValue(myModel);
                    writer.WriteStartElement(p.Name);
                    var myCustomAttribute = p.GetCustomAttributes(typeof(MyCustomAttribute), false).FirstOrDefault() as MyCustomAttribute;
                    if(myCustomAttribute != null)
                    {
                        await writer.WriteAttributeStringAsync(null, "MyType", null, myCustomAttribute.MyType );
                    }
    
                    writer.WriteValue(value);
                    await writer.WriteEndElementAsync();
                });
    
                await writer.WriteEndElementAsync();
                await writer.FlushAsync();
                s.Position = 0;
                doc.Load(s);                
                writer.Close();
            }
            string myXml = doc.OuterXml
    

    In myXml should be something like that: (values are examples)

    <?xml version="1.0" encoding="utf-8"?>
    <Root>
        <Document MyType="word">something</Document>
        <Time MyType="time">11:31:29</Time>
    </Root>
    

    You can do it in other way, of course. Here you have some docs which helped me: https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=netframework-4.8#writing_elements

    0 讨论(0)
  • 2020-11-30 04:29

    Where do you have the type stored?

    Normally you could have something like:

    class Document {
        [XmlAttribute("type")]
        public string Type { get; set; }
        [XmlText]
        public string Name { get; set; }
    }
    
    
    public class _Filter    
    {
        [XmlElement("Times")]    
        public _Times Times;    
        [XmlElement("Document")]    
        public Document Document;    
    }
    
    0 讨论(0)
  • 2020-11-30 04:30

    The string class doesn't have a type property, so you can't use it to create the desired output. You should create a Document class instead :

    public class Document
    {
        [XmlText]
        public string Name;
    
        [XmlAttribute("type")]
        public string Type;
    }
    

    And you should change the Document property to type Document

    0 讨论(0)
提交回复
热议问题