解析C#中的XML数据并显示在列表框中

解析C#中的XML数据并显示在列表框中,c#,xml,visual-studio,parsing,xml-serialization,C#,Xml,Visual Studio,Parsing,Xml Serialization,我试图使用Visual Studio在C#中解析XML文件,并在列表框中显示数据,但在处理嵌套XML文件时,我不知道如何解析它 这是XML文件中的代码: <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE root [ <!ELEMENT root (Persons*)> <!ELEMENT Persons (name)> <!ELEMENT IsMale (#PCDATA)>

我试图使用Visual Studio在C#中解析XML文件,并在列表框中显示数据,但在处理嵌套XML文件时,我不知道如何解析它

这是XML文件中的代码:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE root [
  <!ELEMENT root (Persons*)>
  <!ELEMENT Persons (name)>
  <!ELEMENT IsMale (#PCDATA)>
  <!ELEMENT Age (#PCDATA)>
  <!ELEMENT Name (#PCDATA)>
  <!ELEMENT LikedPerson (name)>
 ]>
<root>
  <Persons name ="Bob">
    <IsMale>true</IsMale>
    <Age>30</Age>
    <LikedPerson name ="Iulia">
      <IsMale>false</IsMale>
      <Age>32</Age>
    </LikedPerson>
  </Persons>
</root>
这是Persons.cs的定义:

class Persons
{
    public string Name { get; private set; }
    public int Age { get; private set; }
    public bool IsMale { get; private set; }
    public Persons LikedPerson { get; private set; }

    public Persons(string name, int age, bool isMale, Persons likedPerson)
    {
        Name = name;
        Age = age;
        IsMale = isMale;
        LikedPerson = likedPerson;
    }
}

您还需要为Persons类添加不带参数的构造函数

您可以像现在一样获取LikedPerson节点并获取其名称/年龄。为了避免代码重复,您可以创建一个方法,该方法接受XmlNode,递归地解析它并返回Person。但更好的方法是使用


最自然的方法是按照建议使用
XmlSerializer
,但要做到这一点,您必须稍微重构您的类:

[XmlType(Namespace="", TypeName="root")]
public class PersonCollection
{
    [XmlElement(Namespace="", ElementName="Persons")]
    public List<Persons> People { get; set; }
}

public class Persons
{
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsMale { get; set; }

    public Persons LikedPerson { get; set; }

    public Persons() { }

    public Persons(string name, int age, bool isMale, Persons likedPerson)
    {
        Name = name;
        Age = age;
        IsMale = isMale;
        LikedPerson = likedPerson;
    }
}
pc.People
列表将包含您的
Persons
对象。

@user3063909

1-对XML定义使用XSD。例:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Persons" maxOccurs="unbounded" minOccurs="0" type="Persons"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="Persons">
    <xs:sequence>
      <xs:element type="xs:string" name="IsMale"/>
      <xs:element type="xs:int" name="Age"/>
      <xs:element name="LikedPerson" type="Persons"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="name" />
  </xs:complexType>
</xs:schema>   

2-Persons类应如下所示:

XmlSerializer ser = new XmlSerializer(typeof(PersonCollection));

PersonCollection pc = (PersonCollection)ser.Deserialize(File.OpenRead("Baza_de_cunostinte.xml"));
foreach (Persons p in pc.People)
{
   // you now have a fully populated object
}
namespace StackOverflow
{
    public class Root
    {
        [XmlElement("Persons")]
        public List<Persons> Persons { get; set; }
    }

    public class Persons
    {
        public string IsMale { get; set; }
        public int Age { get; set; }
        public Persons LikedPerson { get; set; }

        [XmlAttribute("Name")]
        public string Name { get; set; }
    }
}
命名空间堆栈溢出
{
公共类根
{
[XmlElement(“人员”)]
公共列表人员{get;set;}
}
公共阶层人士
{
公共字符串IsMale{get;set;}
公共整数{get;set;}
像person{get;set;}这样的公众人物
[XmlAttribute(“名称”)]
公共字符串名称{get;set;}
}
}
3-序列化程序类:

namespace StackOverflow
{
    public class XmlSerializerHelper<T> where T : class 
    {
        private readonly XmlSerializer _serializer;

        public XmlSerializerHelper()
        {
            _serializer = new XmlSerializer(typeof(T));
        }

        public T BytesToObject(byte[] bytes)
        {
            using (var memoryStream = new MemoryStream(bytes))
            {
                using (var reader = new XmlTextReader(memoryStream))
                {
                    return (T)_serializer.Deserialize(reader);
                }
            }
        }
    }
}
命名空间堆栈溢出
{
公共类XmlSerializerHelper,其中T:class
{
私有只读XmlSerializer\u序列化程序;
公共XMLRHELPER()
{
_serializer=新的XmlSerializer(typeof(T));
}
公共T字节测试对象(字节[]字节)
{
使用(var memoryStream=新的memoryStream(字节))
{
使用(var读取器=新的XmlTextReader(memoryStream))
{
返回(T)\反序列化(读取器);
}
}
}
}
}
4-最后,这样称呼它:

var fileBytes = File.ReadAllBytes("C:/xml.xml");
var persons = new XmlSerializerHelper<Root>().BytesToObject(fileBytes);
var fileBytes=File.ReadAllBytes(“C:/xml.xml”);
var persons=new XmlSerializerHelper().ByTestObject(fileBytes);
结果将是根类,其中包含人员列表


干杯。

它给出了XmlSerializer上的以下错误。。。线路:Proiect_SBC。由于其保护级别,人员无法访问。只能处理公共类型。将类定义公开:公共类Persons{…}现在我在var person=(Persons)mySerializer.Deserialize(myFileStream);->>{“XML文档(10,2)中有一个错误”。}这是一个不错的建议@RadinGospodinov,但如果不对类(或XML)进行重大修改,它将无法工作……我还在Persons.cs中添加了“private System.XML.XmlNode likedPerson;”,现在它在PropertyGrid中显示了“likedPerson”,但旁边没有显示任何内容。。。(如姓名、年龄等)请更新您的密码好吗?我将尝试重现您的问题。我无法评论另一个答案:XML文档(10,2)中存在错误。您的根元素不是“Persons”,这就是为什么会出现此错误。LikedPerson是否会多次出现?您还需要为此更新您的类,因为它现在只能在CLR对象中出现一次。
namespace StackOverflow
{
    public class Root
    {
        [XmlElement("Persons")]
        public List<Persons> Persons { get; set; }
    }

    public class Persons
    {
        public string IsMale { get; set; }
        public int Age { get; set; }
        public Persons LikedPerson { get; set; }

        [XmlAttribute("Name")]
        public string Name { get; set; }
    }
}
namespace StackOverflow
{
    public class XmlSerializerHelper<T> where T : class 
    {
        private readonly XmlSerializer _serializer;

        public XmlSerializerHelper()
        {
            _serializer = new XmlSerializer(typeof(T));
        }

        public T BytesToObject(byte[] bytes)
        {
            using (var memoryStream = new MemoryStream(bytes))
            {
                using (var reader = new XmlTextReader(memoryStream))
                {
                    return (T)_serializer.Deserialize(reader);
                }
            }
        }
    }
}
var fileBytes = File.ReadAllBytes("C:/xml.xml");
var persons = new XmlSerializerHelper<Root>().BytesToObject(fileBytes);