groupName<--object
name<--prop
addres<--prop
phone<--prop
我怎样才能将它重建回相同的结构?
这是我如何将它写入xml
public override void Save(PhoneBook pb)
{
using (XmlWriter writer = XmlWriter.Create(path))
{
writer.WriteStartDocument();
writer.WriteStartElement("Group");
foreach (PhoneBookGroup group in pb.Items)
{
writer.WriteStartElement("GroupName");
writer.WriteElementString("GroupName", group.GroupName.ToString());
foreach (Contect contect in group.Items)
{
writer.WriteStartElement("Addres", contect.Addres.ToString());
writer.WriteStartElement("Number", contect.Number.ToString());
writer.WriteStartElement("Name", contect.Name.ToString());
}
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
答案 0 :(得分:1)
使用XmlSerializer
,当然是第一个版本,因为代码很简单。如果你的老板想要不同在看到序列化版本有多简单且不易出错之后,你应该试着说服他 - 工作的一部分不仅仅是做你所说的,而是至少给出诚实的建议。除非这应该是一次学习经历,否则你的老板错误 - 这很好而且正常,但你应该至少尝试以节省时间和金钱,然后他说。他可能只是没有意识到其他选择。
您的代码示例存在错误这一事实凸显了手动方法的问题 - 您可能意味着writer.WriteElementString("Number",...
而不是WriteStartElement("Number",...
。使用更结构化的方法更加安全和简单。
如果确实需要阅读原始xml,我建议您使用XDocument
类而不是XmlReader
来阅读您的文档和linq to xml提取相关位。那个仍然比XmlReader
更简单,同时保留了手写代码的完全灵活性(它只是慢一点)。如果您坚持XmlReader
解决方案(请注意,这没有技术原因),那么您应该先尝试编写自己的解决方案 - 在问题中包含您的尝试,以便我们可以看到您尝试过的方法。
答案 1 :(得分:1)
看了你的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不可处理,可以使用下面的方法读回到对象中。我从Save代码中假设的唯一方法是有一些从字符串到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;
}