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





