Parsing XML data in C# and show into ListBox

前端 未结 4 2070
灰色年华
灰色年华 2020-12-11 08:36

I am trying to parse a XML file in C# using Visual Studio and show the data in a ListBox, but I don\'t know how to parse it when I\'m dealing with a nested XML file.

相关标签:
4条回答
  • 2020-12-11 08:38
    XmlSerializer mySerializer = new XmlSerializer(typeof(Persons));
    // Create a FileStream or textreader to read the xml data.
    FileStream myFileStream = new FileStream("xmldatafile.xml", FileMode.Open);
    
    var person = (Persons)  mySerializer.Deserialize(myFileStream);
    

    You also need to add constructor without parameter for Persons class.

    0 讨论(0)
  • 2020-12-11 08:40

    @user3063909,

    1- Use a XSD for the XML definition. Ex:

    <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- The Persons class should look like this:

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

    3- The serializer class:

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

    4- And finally, call it this way:

    var fileBytes = File.ReadAllBytes("C:/xml.xml");
    var persons = new XmlSerializerHelper<Root>().BytesToObject(fileBytes);
    

    The result, will be the root class with a list of persons.

    Cheers.

    0 讨论(0)
  • 2020-12-11 08:58

    You can get LikedPerson node and get it's name/age like you do now. In order to avoid code duplication, you can create a method, which takes XmlNode, parses it recursively and returns a Person. But the better way is to use XmlSerializer

    foreach (XmlNode node in doc.DocumentElement) 
    {
        string name = node.Attributes[0].Value;
        int age = int.Parse(node["Age"].InnerText);
        bool isMale = bool.Parse(node["IsMale"].InnerText);
    
        var likedPerson = node.SelectSingleNode("LikedPerson");
    
        if (likedPerson != null){
            string name = likedPerson.Attributes[0].Value;
            //age, gender, etc.        
        }        
    }
    
    0 讨论(0)
  • 2020-12-11 08:59

    The most natural way to do this is to use the XmlSerializer, as suggested, but to do so you'll have to refactor your classes a bit:

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

    Then you can do something like this:

    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
    }
    

    and the pc.People list will contain your Persons objects.

    0 讨论(0)
提交回复
热议问题