我正在编写一个类库,它抽象出网站上XML文件中包含的数据。每个XML文件使用相同的根元素:page
。 page
的后代取决于我正在下载的特定文件。例如:
<!-- http://.../groups.xml -->
<page url="/groups.xml">
<groups>
<group id="1" >
<members>
<member name="Adrian" />
<member name="Sophie" />
<member name="Roger" />
</members>
</group>
</groups>
</page>
<!-- http://.../project.xml?n=World%20Domination -->
<page url="/project.xml">
<projectInfo>
<summary classified="true" deadline="soon" />
<team>
<member name="Pat" />
<member name="George" />
</team>
</projectInfo>
</page>
最后还有一些我想要下载和处理的XML文件。出于这个原因,我一直试图想出一个很好的,干净的方法来反序列化数据。我尝试了一些方法,但是当我回顾我的代码时,每种方法都让我觉得有点脏。我最新的化身使用以下方法:
internal class Provider
{
/// <summary>Download information from the host.</summary>
/// <typeparam name="T">The type of data being downloaded.</typeparam>
internal T Download<T>(string url) where T : IXmlSerializable, new()
{
try
{
var request = (HttpWebRequest)WebRequest.Create(url);
var response = (HttpWebResponse)request.GetResponse();
using (var reader = XmlReader.Create(response.GetResponseStream()))
{
// Skip the XML prolog (declaration and stylesheet reference).
reader.MoveToContent();
// Skip the `page` element.
if (reader.LocalName == "page") reader.ReadStartElement();
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(reader);
}
}
catch (WebException ex) { /* The tubes are clogged. */ }
}
}
[XmlRoot(TypeName = "groups")]
public class GroupList : List<Group>, IXmlSerializable
{
private List<Group> _list;
public void ReadXml(XmlReader reader)
{
if (_list == null) _list = new List<Group>();
reader.ReadToDescendant("group");
do
{
var id = (int)reader["id"];
var group = new Group(id);
if (reader.ReadToDescendant("member"))
{
do
{
var member = new Member(reader["name"], group);
group.Add(member);
} while (reader.ReadToNextSibling("member"));
}
_list.Add(group);
} while (reader.ReadToNextSibling("group"));
reader.Read();
}
}
这有效,但我觉得有一种更好的方式,我没有看到。我在启动这个项目时尝试使用xsd.exe
实用程序。虽然它可以最大限度地减少我编写的代码量,但它并不是理想的解决方案。这将是我现在使用的相同方法 - 我会更快地到达那里。我正在寻找更好的解决方案。所有页面都有page
元素的共同点 - 是不是有办法利用它?是否可以拥有一个可序列化的容器类Page
,它可能包含其他对象的组合,具体取决于下载的文件?有没有更简单的方法来实现这个目标?
答案 0 :(得分:5)
.NET在命令行上提供了“xsd.exe”实用程序。
在原始xml文件上运行xsd.exe (xmlfilename)
,它将从XML数据文件中派生出XML架构(xsd)。
运行xsd.exe (xsd file name) /C
,它将创建一个C#类,可用于将这样的XML文件反序列化为C#类。
当然,由于它只有一个XML文件可供使用,因此xsd.exe在其衍生的XML模式中并不完美 - 但这可能是您开始使用的快捷方式。< / p>