如何在流式传输XML文档时返回强类型对象而不是xelement
本文关键字:对象 强类型 返回 xelement 文档 XML 传输 | 更新日期: 2023-09-27 18:12:59
我希望能够从流式传输XML文档的代码中返回强类型对象,而不是xelement。假设所讨论的XML文档是:
<?xml version="1.0" encoding="utf-8" ?>
<People>
<Person>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</Person>
<Person>
<FirstName>Adam</FirstName>
<LastName>Smith</LastName>
</Person>
<Person>
<FirstName>Jane</FirstName>
<LastName>Smith</LastName>
</Person>
</People>
目前,我的阅读器代码看起来像这样:
public class PeopleReader
{
public static IEnumerable<XElement> StreamPerson(string path)
{
using (XmlReader rdr = XmlReader.Create(path))
{
rdr.MoveToContent();
while (rdr.Read())
{
if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "Person")
{
XElement item = XElement.ReadFrom(rdr) as XElement;
if (item != null)
yield return item;
}
}
}
}
}
当前主叫码为:
// Current implementation
foreach (var person in PeopleReader.StreamPerson(@"...'People.xml"))
{
MessageBox.Show(person.Element("LastName").Value);
}
我必须调用.Element
和.Value
。
我想要的调用代码是:
// Required implementation where person is returned as a strongly typed obj.
foreach (var person in PeopleReader.StreamPerson(@"...'People.xml"))
{
MessageBox.Show(person.LastName);
}
我知道我可以使用xsd.exe生成。xsd文件,然后生成。cs文件,但我不清楚实际步骤。此外,我不确定如何更改阅读器代码以返回生成的类,以便调用代码接收要枚举的强类型对象?也就是说,我如何从xelement转换到强类型类—强制类型转换似乎不是一种选择?
我正在使用VS2015,如果可能的话,我宁愿不使用第三方工具。
提前感谢。
我建议您使用XmlSerializer
。
var serializer = new XmlSerializer(typeof(Person));
using (var rdr = XmlReader.Create(path))
{
rdr.MoveToContent();
while (rdr.Read())
{
if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "Person")
{
yield return (Person) serializer.Deserialize(rdr);
}
}
}
你的类定义如下:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
请看下面的示例。
要为XML生成类,您可以使用xsd.exe
(用于XML或XML模式,如果您有的话),或者您可以使用Edit -> Paste Special -> Paste XML as Classes
将XML样本复制并粘贴到Visual Studio中。
不返回IEnumerable<XElement>
,而是创建Person
类型并返回IEnumerable<Person>
:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
然后返回它的一个新实例:
public static IEnumerable<XElement> StreamPerson(string path)
{
using (XmlReader rdr = XmlReader.Create(path))
{
rdr.MoveToContent();
while (rdr.Read())
{
XElement item = XElement.ReadFrom(rdr) as XElement;
if (item != null)
{
yield return new Person
{
FirstName = item.Element("FirstName")?.Value,
LastName = item.Element("LastName")?.Value
};
}
}
}
}
更新 -在理解这些xml表示较大类的"轻量级"版本,并且这些类的源代码引用到当前项目之后,我建议:
创建包含轻量级属性的较大类的基类。这样您就不会有代码重复,并且可以从一个转换到另一个。
public class PersonBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Person : PersonBase
{
public string OtherProperty { get; set; }
}
然后使用我上面的方法或者Charles