C# XML 非嵌套序列化 arrays/list
C# XML Serialization un-nested arrays/list
我正在编写一个 C# WinForm
应用程序,它应该读取一个预先存在的 XML
文件。
我需要解析 XML
文件并建立一个数据结构来反映 XML
文件内容。
我在 XML
序列化方面有一些经验,因此我想使用 .NET
XML.Serialization
功能。
我陷入了一个奇怪的 XML
结构,我无法在 class 中匹配(通过属性、元素等):
<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>
其中的 'weird' 部分是评论列表。我习惯于使用 XmlArray 指令对 list/array 元素进行序列化,从而找到此类 'repeating' 项。无论如何使用这种方法都会引入一个包围标签来包含项目列表。在这种情况下我怎样才能'reflect'这个结构呢?
这是我应该使用的代码(没有 'missing' 注释):
[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; }
}
我还有另一个问题。反映此结构的最佳 class 层次结构是:
a) 以与 xml 元素相同的方式嵌套 classes
b) 将所有 classes 保持在同一级别(没有层次结构)?
有副作用需要考虑吗?
您可以按如下方式定义 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; }
}
现在我们可以使用这些实体 Deserialize
给定 Xml。
XmlSerializer serializer = new XmlSerializer(typeof(Sheet));
StreamReader reader = new StreamReader(filepath);
var sheet = (Sheet)serializer.Deserialize(reader);
reader.Close();
检查这个 Demo code
试试这个...
使用
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 的对象....
我正在编写一个 C# WinForm
应用程序,它应该读取一个预先存在的 XML
文件。
我需要解析 XML
文件并建立一个数据结构来反映 XML
文件内容。
我在 XML
序列化方面有一些经验,因此我想使用 .NET
XML.Serialization
功能。
我陷入了一个奇怪的 XML
结构,我无法在 class 中匹配(通过属性、元素等):
<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>
其中的 'weird' 部分是评论列表。我习惯于使用 XmlArray 指令对 list/array 元素进行序列化,从而找到此类 'repeating' 项。无论如何使用这种方法都会引入一个包围标签来包含项目列表。在这种情况下我怎样才能'reflect'这个结构呢? 这是我应该使用的代码(没有 'missing' 注释):
[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; }
}
我还有另一个问题。反映此结构的最佳 class 层次结构是: a) 以与 xml 元素相同的方式嵌套 classes b) 将所有 classes 保持在同一级别(没有层次结构)? 有副作用需要考虑吗?
您可以按如下方式定义 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; }
}
现在我们可以使用这些实体 Deserialize
给定 Xml。
XmlSerializer serializer = new XmlSerializer(typeof(Sheet));
StreamReader reader = new StreamReader(filepath);
var sheet = (Sheet)serializer.Deserialize(reader);
reader.Close();
检查这个 Demo code
试试这个...
使用
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 的对象....