C#XML Serialization非嵌套数组/列表

时间:2016-04-02 08:08:02

标签: c# xml xml-serialization

我正在编写一个应该读取预先存在的WinForm文件的C#XML应用程序。 我需要解析XML文件并构建数据结构以反映XML文件内容。 我在XML序列化方面有一些经验,因此我尝试使用.NET XML.Serialization功能。 我遇到了一个奇怪的XML结构,我无法在类中匹配(通过属性,元素等):

<sheet number="1" name="/" tstamps="/">
  <title_block>
    <title>ECC Push-Pull</title>
    <company/>
    <rev>0.1</rev>
    <date>Sat 21 Mar 2015</date>
    <source>ecc83-pp.sch</source>
    <comment number="1" value=""/>
    <comment number="2" value=""/>
    <comment number="3" value=""/>
    <comment number="4" value=""/>
  </title_block>
</sheet>

这个'怪异'部分是评论列表。我习惯于使用XmlArray指令序列化列表/数组元素来找到这样的“重复”项。无论如何使用这种方法会引入一个环绕标记来包括项目列表。在这种情况下,我怎么能'反映'这个结构? 这是我应该使用的代码(没有'缺失'评论):

[XmlRoot("sheet")]
public class Sheet
{
    [XmlAttribute("number")]
    public int Number { get; }

    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlAttribute("tstamps")]
    public UInt32 TimeStamps { get; set; }

    [XmlElement]
    public SheetTitle Title { get; set; }

    public Sheet()
    {
        Title = new SheetTitle();
    }
}


[XmlRoot("title_block")]
public class SheetTitle
{
    [XmlElement("title")]
    public string Title { get; set; }

    [XmlElement("company")]
    public string Company { get; set; }

    [XmlElement("rev")]
    public string Revision { get; set; }

    [XmlElement("date")]
    public DateTime Date { get; set; }

    [XmlElement("source")]
    public string Source { get; set; }

    public SheetTitle()
    {
        Date = DateTime.Now;
    }
}

[XmlRoot("comment")]
public class Comment
{
    [XmlAttribute("number")]
    public int Number { get; set; }

    [XmlAttribute("value")]
    public string Value { get; set; }
}

我有另一个问题。反映此结构的最佳类层次结构是: a)以与xml元素相同的方式嵌套类 b)将所有类保持在同一级别(没有层次结构)? 是否有副作用需要考虑?

2 个答案:

答案 0 :(得分:1)

您可以按如下方式定义C#个对象。

[XmlRoot(ElementName="comment")]
public class Comment {
    [XmlAttribute(AttributeName="number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName="value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName="title_block")]
public class Title_block {
    [XmlElement(ElementName="title")]
    public string Title { get; set; }
    [XmlElement(ElementName="company")]
    public string Company { get; set; }
    [XmlElement(ElementName="rev")]
    public string Rev { get; set; }
    [XmlElement(ElementName="date")]
    public string Date { get; set; }
    [XmlElement(ElementName="source")]
    public string Source { get; set; }
    [XmlElement(ElementName="comment")]
    public List<Comment> Comment { get; set; }
}

[XmlRoot(ElementName="sheet")]
public class Sheet {
    [XmlElement(ElementName="title_block")]
    public Title_block Title_block { get; set; }
    [XmlAttribute(AttributeName="number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName="tstamps")]
    public string Tstamps { get; set; }
}

现在我们可以将这些实体用于给定Xml的Deserialize

XmlSerializer serializer = new XmlSerializer(typeof(Sheet));

StreamReader reader = new StreamReader(filepath);
var sheet = (Sheet)serializer.Deserialize(reader);
reader.Close();

选中此Demo code

答案 1 :(得分:1)

试试这个......

Usings

using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

[XmlRoot(ElementName = "comment")]
public class Comment
{
    [XmlAttribute(AttributeName = "number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName = "value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "title_block")]
public class Title_block
{
    [XmlElement(ElementName = "title")]
    public string Title { get; set; }
    [XmlElement(ElementName = "company")]
    public string Company { get; set; }
    [XmlElement(ElementName = "rev")]
    public string Rev { get; set; }
    [XmlElement(ElementName = "date")]
    public string Date { get; set; }
    [XmlElement(ElementName = "source")]
    public string Source { get; set; }
    [XmlElement(ElementName = "comment")]
    public List<Comment> Comment { get; set; }
}

[XmlRoot(ElementName = "sheet")]
public class Sheet
{
    [XmlElement(ElementName = "title_block")]
    public Title_block Title_block { get; set; }
    [XmlAttribute(AttributeName = "number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "tstamps")]
    public string Tstamps { get; set; }
}

代码

try
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load("xml.xml");

    string XML = xmlDoc.InnerXml.ToString();
    byte[] BUFXML = ASCIIEncoding.UTF8.GetBytes(XML);
    MemoryStream ms1 = new MemoryStream(BUFXML);

    XmlSerializer DeserializerPlaces = new XmlSerializer(typeof(Sheet));
    using (XmlReader reader = new XmlTextReader(ms1))
    {
        Sheet dezerializedXML = (Sheet)DeserializerPlaces.Deserialize(reader);

    }// Put a break-point here, then mouse-over dezerializedXML and you should have you values
}
catch (System.Exception)
{
    throw;
}

此代码从文件(在应用程序* .exe文件夹中称为xml.xml)中读取xml,然后将其解释为名为dezerializedXML的对象....

相关问题