C# XmlReader返回到对象列表
嘿,我很难“重建”(读取)我的对象。我的结构非常简单:C# XmlReader返回到对象列表,c#,xml,C#,Xml,嘿,我很难“重建”(读取)我的对象。我的结构非常简单: groupName<--object name<--prop addres<--prop phone<--prop 使用XmlSerializer,当然是第一个版本,因为它对代码来说很简单。如果你的老板在看到序列化版本是多么的简单和不容易出错后,希望它有所不同,那么你应该试着说服他不要这样做——工作的一部分不仅仅是按照你说的去做,而是至少给出诚实的建议。除非这是一次学习经历,否则你的老板是错的——这
groupName<--object
name<--prop
addres<--prop
phone<--prop
使用
XmlSerializer
,当然是第一个版本,因为它对代码来说很简单。如果你的老板在看到序列化版本是多么的简单和不容易出错后,希望它有所不同,那么你应该试着说服他不要这样做——工作的一部分不仅仅是按照你说的去做,而是至少给出诚实的建议。除非这是一次学习经历,否则你的老板是错的——这很正常,但你至少应该在按照他说的去做之前尽量节省时间和金钱。他可能只是没有意识到其他选择
手动方法的问题突出表现在以下事实上:您的代码示例有缺陷——您可能指的是writer.WriteElementString(“Number”,…
,而不是WriteStarteElement(“Number”,…
。使用更结构化的方法更安全、更简单
如果您真的需要阅读原始xml,我建议您在
XmlReader
上使用XDocument
类来阅读文档,并使用linq to xml来提取相关位。这比XmlReader
更简单,同时保留了手写代码的全部灵活性(只是稍微慢一点)。如果您坚持使用XmlReader
解决方案(请注意,没有技术原因),然后您应该先尝试编写自己的模式-将您的尝试包括在您的问题中,以便我们可以看到您的尝试。查看了您的xml输出后,我会认真考虑更改您的模式,因为Save函数的输出创建了结构非常奇怪的xml,我认为这是您努力重建它的原因当前输出将如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Group>
<GroupName>
<GroupName>groupName</GroupName>
<Addres xmlns="addy">
<Number xmlns="0123456789">
<Name xmlns="Henry">
<Addres xmlns="address2">
<Number xmlns="9876543210">
<Name xmlns="Dave" />
<GroupName>
<GroupName>secondGroup</GroupName>
<Addres xmlns="fleet">
<Number xmlns="0123456789">
<Name xmlns="Me" />
</Number>
</Addres>
</GroupName>
</Number>
</Addres>
</Name>
</Number>
</Addres>
</GroupName>
</Group>
组名
第二组
话虽如此,生成的xml不是不可处理的,可以使用下面的方法读回对象。我从您的保存代码中假设的唯一一件事是,有某种方法可以从字符串获取到GroupName对象(因为您使用的是ToString方法将值获取到xml中).在我的测试中,我使用隐式转换运算符实现了该对象,如下所示
class GroupName
{
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
// Specific conversion from string to GroupName object
public static implicit operator GroupName(string s)
{
return new GroupName() { Name = s };
}
}
public PhoneBook Rebuild()
{
using (XmlReader reader = XmlReader.Create(path))
{
// read to the start of the xml
reader.MoveToContent();
// create the return object
PhoneBook returnObject = new PhoneBook();
returnObject.Items = new List<PhoneBookGroup>();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
// read each GroupName Node as a separate node collection
if (reader.Name == "GroupName")
{
// This is the root node of the groups
PhoneBookGroup grp = null;
Contact currentContact = null;
// loop the reader from this starting node
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "GroupName":
if (grp == null)
{
grp = new PhoneBookGroup();
returnObject.Items.Add(grp);
// must implement an implicit operator between string and GroupName object
grp.Name = (GroupName)reader.ReadElementString();
}
else
{
// start of a new group, so null what we have so far and start again
grp = null;
}
break;
case "Addres":
// Address is the start node for a contact so create a new contact and start filling it
currentContact = new Contact();
if (grp.Items == null)
{
grp.Items = new List<Contact>();
}
grp.Items.Add(currentContact);
// due to the way the xml is being written the value is held as the namespace !!!
currentContact.Address = reader.NamespaceURI;
break;
case "Number":
// due to the way the xml is being written the value is held as the namespace !!!
currentContact.Phone = reader.NamespaceURI;
break;
case "Name":
// due to the way the xml is being written the value is held as the namespace !!!
currentContact.Name = reader.NamespaceURI;
break;
default:
break;
}
}
}
}
}
}
return returnObject;
}
类组名
{
公共字符串名称{get;set;}
公共重写字符串ToString()
{
返回此.Name;
}
//从字符串到GroupName对象的特定转换
公共静态隐式运算符GroupName(字符串s)
{
返回新的GroupName(){Name=s};
}
}
公共电话簿重建()
{
使用(XmlReader=XmlReader.Create(path))
{
//读到xml的开头
reader.MoveToContent();
//创建返回对象
PhoneBook returnObject=新建电话簿();
returnObject.Items=新列表();
while(reader.Read())
{
if(reader.NodeType==XmlNodeType.Element)
{
//将每个GroupName节点作为单独的节点集合读取
if(reader.Name==“GroupName”)
{
//这是组的根节点
PhoneBookGroup grp=null;
触点电流触点=零;
//从此起始节点循环读卡器
while(reader.Read())
{
if(reader.NodeType==XmlNodeType.Element)
{
开关(reader.Name)
{
案例“GroupName”:
if(grp==null)
{
grp=新电话簿组();
returnObject.Items.Add(grp);
//必须在string和GroupName对象之间实现隐式运算符
grp.Name=(GroupName)reader.ReadElementString();
}
其他的
{
//开始一个新的小组,所以空的,我们到目前为止,并重新开始
grp=null;
}
打破
案例“地址”:
//地址是联系人的起始节点,因此创建一个新联系人并开始填充它
currentContact=新触点();
if(grp.Items==null)
{
grp.Items=新列表();
}
grp.Items.Add(当前联系人);
//由于xml的编写方式,该值被保留为名称空间!!!
currentContact.Address=reader.NamespaceURI;
打破
案例“编号”:
//由于xml的编写方式,该值被保留为名称空间!!!
currentContact.Phone=reader.NamespaceURI;
打破
案例“名称”:
//由于xml的编写方式,该值被保留为名称空间!!!
currentContact.Name=reader.Na
class GroupName
{
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
// Specific conversion from string to GroupName object
public static implicit operator GroupName(string s)
{
return new GroupName() { Name = s };
}
}
public PhoneBook Rebuild()
{
using (XmlReader reader = XmlReader.Create(path))
{
// read to the start of the xml
reader.MoveToContent();
// create the return object
PhoneBook returnObject = new PhoneBook();
returnObject.Items = new List<PhoneBookGroup>();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
// read each GroupName Node as a separate node collection
if (reader.Name == "GroupName")
{
// This is the root node of the groups
PhoneBookGroup grp = null;
Contact currentContact = null;
// loop the reader from this starting node
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "GroupName":
if (grp == null)
{
grp = new PhoneBookGroup();
returnObject.Items.Add(grp);
// must implement an implicit operator between string and GroupName object
grp.Name = (GroupName)reader.ReadElementString();
}
else
{
// start of a new group, so null what we have so far and start again
grp = null;
}
break;
case "Addres":
// Address is the start node for a contact so create a new contact and start filling it
currentContact = new Contact();
if (grp.Items == null)
{
grp.Items = new List<Contact>();
}
grp.Items.Add(currentContact);
// due to the way the xml is being written the value is held as the namespace !!!
currentContact.Address = reader.NamespaceURI;
break;
case "Number":
// due to the way the xml is being written the value is held as the namespace !!!
currentContact.Phone = reader.NamespaceURI;
break;
case "Name":
// due to the way the xml is being written the value is held as the namespace !!!
currentContact.Name = reader.NamespaceURI;
break;
default:
break;
}
}
}
}
}
}
return returnObject;
}