简体   繁体   中英

C# XML Linq Pointing to/Reading Node

I can't seem to point and read the correct information. I'm new to using Linq and have tried (after loading the document as XDocument and XElement) select, root.xelement, descendant, element, node etc. and haven't found the proper way of pointing to what I'm trying to target. I have an XML document that looks like this for now.

<Contacts>
   <EntryName>
     <Name>NAME1</Name>
     <Email>EMAIL</Email>
     <EIL>1</EIL>
     <Notes>Notes</Notes>
   </EntryName>
</Contacts>

I need to pull up a list of all EntryNames and place them in listBox1. When a user selects one, it gathers it takes the "listBox1.SelectedItem" and gather's the email address associated and places it in a textBox. "EntryName" during runtime is replaced by a textfield. My most recent try was this:

    var xml = XDocument.Load(apppath + @"\Contacts.clf");
    var entries = xml.Element("Contacts").Value.ToString();

        foreach (var entry in entries)
        {
            listBox1.Items.Add(entry.ToString());
        }

Which gets me nothing but characters at a time of the complete file due to the foreach function. What I'm looking for is in the listBox from Contacts:

EntryName
EntryName2
EntryName2...etc

and when selected (from say EntryName2) it pulls the email field and places it in a textbox. Please forgive and obvious or dumb mistake, very new to this. Thanks.

Try this. I believe you were trying to query the Name elements in your XML document.

var xml = XDocument.Load(apppath + @"\Contacts.clf");
var entries = from entryName in xml.Descendants("EntryName") select (string)entryName.Element("Name");

foreach (var entry in entries)
{
   listBox1.Items.Add(entry);
}

I wrote a quick example on how to achieve this

public partial class Form1 : Form
{
    XDocument doc;
    public Form1()
    {
        InitializeComponent();

        doc = XDocument.Load(apppath + @"\Contacts.clf");
        var entryNames = doc.Root.Elements("EntryName")
            .Select(elem => elem.Element("Name").Value ).ToArray();
        listBox1.Items.AddRange(entryNames);
    }

    private void listBox1_SelectedValueChanged(object sender, EventArgs e)
    {
        textBox1.Text = doc.Root.Elements("EntryName")
            .FirstOrDefault(node => node.Element("Name").Value == listBox1.SelectedItem.ToString())
            .Element("Email").Value;

    }
}

However That seems like too much trouble to find the Email. I would, instead handle it like this:

public partial class Form1 : Form
{
    XDocument doc;
    public Form1()
    {
        InitializeComponent();
        String apppath = ".";
        doc = XDocument.Load(apppath + @"\Contacts.clf");
        var contacts = doc.Root.Elements("EntryName")
            .Select( elem =>
                new Contact { 
                    Name =  elem.Element("Name").Value,
                    Email = elem.Element("Email").Value,
                    EIL = elem.Element("EIL").Value,
                    Notes = elem.Element("Notes").Value
            }
        ).ToList();
        listBox1.DataSource = contacts;
        listBox1.DisplayMember = "Name";
    }

    private void listBox1_SelectedValueChanged(object sender, EventArgs e)
    {
        textBox1.Text = (listBox1.SelectedItem as Contact).Email;
    }        
}

public class Contact
{
    public String Name { get; set; }
    public String Email { get; set; }
    public String EIL { get; set; }
    public String Notes { get; set; }
}

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