Innholdet i en XML-fil
Versjon 1
Versjon en er basert på en egen klasse, nodeLink, som kopler det XML-elementet vi vil vise fram i lista med en presentasjons metode, ToString. Klassen er slik:
// This class represent a DOM-element in the listBox public class nodeLink : Object { XmlElement XMLElt; public nodeLink(XmlElement elt) { XMLElt = elt; } public override string ToString() {return XMLElt.FirstChild.InnerText;} public XmlElement getElement { get { return XMLElt; } } }
Objekter av typen nodeLink representerer en personnode i listeboksen. Vi ser at en array av objekter av denne typen er en slags indextabell som hjelper oss å representere en person i listeboksen: ToString produserer den teksten som går inn i listeboksen, mens XMLElt er det elementet i XML-treet teksten representerer.
Selve formen er slik:
public partial class Form1 : Form { XmlDocument doc = null; public Form1() { InitializeComponent(); } // load the file and fill the listbox private void buttonLoad_Click(object sender, EventArgs e) { textBox1.Text = ""; // load the file and establish DOM doc = new XmlDocument(); try { // assume file in startup catalog doc.Load(Path.Combine(Application.StartupPath, "xmlfil.xml")); XmlNodeList list = doc.GetElementsByTagName("person"); for (int ix = 0; ix < list.Count; ix++) listBoxItems.Items.Add( new nodeLink((XmlElement)list.Item(ix))); listBoxItems.Refresh(); } catch (Exception ex) { // errormessage in the textbox textBox1.Text = ex.Message; } } // pick up click and display items content private void listBoxItems_MouseClick(object sender, MouseEventArgs e) { // we have clicked on a listitem, which one ? nodeLink selected = (nodeLink)listBoxItems.SelectedItem; XmlElement p = selected.getElement; textBox1.Text = String.Format("{0} {1} fra {2} ", p.GetElementsByTagName("f-navn")[0].InnerText, p.GetElementsByTagName("e-navn")[0].InnerText, p.GetElementsByTagName("adr")[0].InnerText); } }
Løsningen med å bruke tekstfeltet til to ting, presentasjon av data for en person og feilmelding ved feil i XML-fila, er neppe i tråd med god design.
Versjon 2
I denne versjonen kutter vi ut klassen som pakker inn XML-elementet, nodelink. I stedet oppretter vi et bindingSource objekt med XmlElement som datasource, og vi lar listeboksen bruke dette objektet som dataSource og innerText som DisplayMember.
Vi pakkker bare etternavnet inn i listeboksen og finner hele personelement som parentNode når vi skal vise fram informasjonen om en person.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Xml; using System.IO; namespace testingxml { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // load the file and fill the listbox // the bindigsource has datasource XmlElement // the list has Displaymember innerText private void buttonLoad_Click(object sender, EventArgs e) { textBox1.Text = ""; // load the file and establish DOM XmlDocument doc = new XmlDocument(); try { // assume file in startup catalog doc.Load(Path.Combine(Application.StartupPath,"xmlfil.xml")); // we want to put e-navn in the list XmlNodeList list = doc.GetElementsByTagName("e-navn"); for (int ix = 0; ix < list.Count; ix++) bindingSource1.Add(list.Item(ix)); listBoxItems.Refresh(); } catch (Exception ex) { // errormessage in the textbox textBox1.Text = ex.Message; } } // pick up click and display items content private void listBoxItems_MouseClick(object sender, MouseEventArgs e) { // we have clicked on a listitem, which one ? XmlElement p_en = (XmlElement)listBoxItems.SelectedItem; // get the person element XmlElement p = (XmlElement)p_en.ParentNode; textBox1.Text = String.Format("{0} {1} fra {2} ", p.GetElementsByTagName("f-navn")[0].InnerText, p.GetElementsByTagName("e-navn")[0].InnerText, p.GetElementsByTagName("adr")[0].InnerText); } } }