【问题标题】:Serializing a XML Document with 3 Levels序列化具有 3 个级别的 XML 文档
【发布时间】:2021-02-16 10:15:18
【问题描述】:

例如,我正在尝试以指定格式获取我的输出 预期

<?xml version="1.0"?>
<xml>
    <JournalEntries>
      <JournalEntry>
        <Field1>SampleOne</Field1>
        <Field2>SampleTwo</Field2>
      </JournalEntry>
      <JournalEntry>
        <Field1>SampleOne</Field1>
        <Field2>SampleTwo</Field2>
      </JournalEntry>
    </JournalEntries>
</xml>

我当前的输出:

<?xml version="1.0"?>
<xml>
  <JournalEntry>
    <Field1>SampleOne</Field1>
    <Field2>SampleTwo</Field2>
  </JournalEntry>
  <JournalEntry>
    <Field1>SampleOne</Field1>
    <Field2>SampleTwo</Field2>
  </JournalEntry>
</xml>

所以本质上我需要添加另一个 root 吗?从某种意义上说,在开头和结尾都有一个JournalEntries。由于一组条目由多个条目组成

[XmlRoot(ElementName = "xml")]
    public class JournalDocument
    {
        
        public JournalDocument()
        {
        }

        public JournalDocument(UnProcessedDocument input)
        {
            input.Body.ForEach(o =>
            {
                JournalEntries.Add(new JournalEntry
                {
                    Field1 = "SampleOne"
                    Field2 = "SampleTwo"
                }); ;
            });
        }

        [XmlElement("JournalEntry")]
        public List<JournalEntry> JournalEntries { get; set; } = new List<JournalEntry>();
    }

    public class JournalEntry
    {
        public string Field1 {get;set;}

        public string Field2 {get;set}
    }

我不知道我定义的根和元素是否在正确的位置,我尝试移动它们但没有运气..例如我尝试将[XmlRoot(ElementName = "JournalEntries")] 放在我的JournalEntry 类上方

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    我更喜欢使用IXmlSerializable。 它对我来说更灵活,让您可以更好地控制序列化。

    例子:

    public class JournalDocument : IXmlSerializable
        {
            public XmlSchema GetSchema() => null;
            public void WriteXml(XmlWriter writer)
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("xml");
                writer.WriteStartElement("JournalEntries")
                if(this.JournalEntries.Count != 0)
                {
                    foreach(JournalEntrie entrie in this.JournalEntries)
                    {
                         writer.WriteStartElement("JournalEntrie");
                         writer.WriteElementString("Field1", entrie.Field1)
                         writer.WriteElementString("Field2", entrie.Field2)
                         writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();
                writer.WriteEndDocument(); // close all open elements
            }
            public void ReadXml(XmlReader reader)
            {
                while(reader.Read())
                {
                    if(reader.NodeType == XmlNodeType.element)
                    {
                        JournalEntrie entrie;
                        switch(reader.Name)
                        {
                            case "JournalEntrie":
                                entrie = new JournalEntrie();
                                break;
                            case "Field1":
                                entire.Field1 = reader.ReadElementContentAsString();
                                break;
    
                           // Now make this for every element.
                        }
                    }
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      虽然 IXMLSerializer 是一个选项,但我最终还是创建了一个扩展方法

      public static string Serialize<T>(this object obj)
              {
                  XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                  ns.Add("", "");
                  var xmlWriterSettings = new XmlWriterSettings() { Indent = true };
                  XmlSerializer serializer = new XmlSerializer(typeof(T));
                  var stringWriter = new StringWriter();
                  using var writer = XmlWriter.Create(stringWriter, xmlWriterSettings);
                  serializer.Serialize(writer, obj, ns);
                  writer.Close();
                  return stringWriter.ToString();
              }
      

      我的主要代码可以与 [XmlRoot(ElementName = "xml")] 保持相同,但只需删除 [XmlElement("JournalEntry")]

      这最终解决了我的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-31
        • 2020-11-20
        • 1970-01-01
        相关资源
        最近更新 更多