简体   繁体   中英

C# XML Parsing with multiple nodes

I have a file that is formatted roughly like: what i want to do is get the Type element then get the data for each source and output it to text fields. Cant seem to get it working.` What is the best way to parse this?

 <Config>
     <Type>8_Port_Switch</Type>      `
        <Inputs>
              <Source_1>
                <Source_1_Name>BobsPC</Source_1_Name>
                <Source_1_Input>7</Source_1_Input>
              </Source_1>
             <Source_2>
               <Source_2_Name>Office</Source_2_Name>
               <Source_2_Input>4</Source_2_Input>
             </Source_2>
             <Source_3>
              <Source_3_Name>Printer</Source_3_Name>
              <Source_3_Input>3</Source_3_Input>
            </Source_3>
   </Config>

this file can be up to 32 ports. I want to use the type info to force a particular form to open then populate the form with the results of the read.

i have a label for each source and 2 text boxes for Name and Input that i want to populate

for example. I want to read the data and populate: enter image description here

edit the information. Then create a new xml doc and upload to the server. I can create with no issues. Its just reading it and passing it back into the fields.

Try following :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("Config").Select(x => new {
                name = (string)x.Element("Type"),
                type = x.Element("Inputs").Elements().Select(y => new
                {
                    id = y.Name.LocalName,
                    name = (string)y.Elements().First(),
                    input = (int)y.Elements().Last()
                }).ToList()
            }).ToList();

        }
    }
}

Option 1

I think a clean approach will be to throw the contents of your XML into a DataSet and then bind your form's controls to the table. Here is an example to help you:

DataSet ds = new DataSet();
ds.readxml("XML File Path");

var bs = new BindingSource();
bs.DataSource = ds;
bs.DataMember = ds.table[0].tablename;

textBox1.DataBindings.Add("FirstName", bs, "Table Name");
textBox2.DataBindings.Add("FirstName", bs, "Table Name");

Option 2

You can use my answer here to create a C# class for your xml. Then deserialize the xml contents into the C# class. Once you have deserialized it into the C# class, you can work and manipulate the instance of the class. You can even bind the instance to your form. The form controls can change the contents of the instance like any C# class instance.

Once you are done, you can then serialize back to xml. Here is the class that was generated for your XML:

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Config
{

    private string typeField;

    private ConfigInputs inputsField;

    /// <remarks/>
    public string Type
    {
        get
        {
            return this.typeField;
        }
        set
        {
            this.typeField = value;
        }
    }

    /// <remarks/>
    public ConfigInputs Inputs
    {
        get
        {
            return this.inputsField;
        }
        set
        {
            this.inputsField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputs
{

    private ConfigInputsSource_1 source_1Field;

    private ConfigInputsSource_2 source_2Field;

    private ConfigInputsSource_3 source_3Field;

    /// <remarks/>
    public ConfigInputsSource_1 Source_1
    {
        get
        {
            return this.source_1Field;
        }
        set
        {
            this.source_1Field = value;
        }
    }

    /// <remarks/>
    public ConfigInputsSource_2 Source_2
    {
        get
        {
            return this.source_2Field;
        }
        set
        {
            this.source_2Field = value;
        }
    }

    /// <remarks/>
    public ConfigInputsSource_3 Source_3
    {
        get
        {
            return this.source_3Field;
        }
        set
        {
            this.source_3Field = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputsSource_1
{

    private string source_1_NameField;

    private byte source_1_InputField;

    /// <remarks/>
    public string Source_1_Name
    {
        get
        {
            return this.source_1_NameField;
        }
        set
        {
            this.source_1_NameField = value;
        }
    }

    /// <remarks/>
    public byte Source_1_Input
    {
        get
        {
            return this.source_1_InputField;
        }
        set
        {
            this.source_1_InputField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputsSource_2
{

    private string source_2_NameField;

    private byte source_2_InputField;

    /// <remarks/>
    public string Source_2_Name
    {
        get
        {
            return this.source_2_NameField;
        }
        set
        {
            this.source_2_NameField = value;
        }
    }

    /// <remarks/>
    public byte Source_2_Input
    {
        get
        {
            return this.source_2_InputField;
        }
        set
        {
            this.source_2_InputField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputsSource_3
{

    private string source_3_NameField;

    private byte source_3_InputField;

    /// <remarks/>
    public string Source_3_Name
    {
        get
        {
            return this.source_3_NameField;
        }
        set
        {
            this.source_3_NameField = value;
        }
    }

    /// <remarks/>
    public byte Source_3_Input
    {
        get
        {
            return this.source_3_InputField;
        }
        set
        {
            this.source_3_InputField = value;
        }
    }
}

Your xml had some errors and I had to fix them such as the closing tags were missing. Then I used the following code to change one thing and then resave it. It worked:

var serializer = new XmlSerializer(typeof(Config));
var reader = new StreamReader("StackQuestion.xml");
var result = serializer.Deserialize(reader) as Config;
reader.Close();
result.Inputs.Source_1.Source_1_Name = "CodingYoshi";

serializer.Serialize(new StreamWriter("StackQuestion.xml"), result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM