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;
}