我正在编写一个应该读取预先存在的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)将所有类保持在同一级别(没有层次结构)? 是否有副作用需要考虑?
答案 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的对象....