Utvalg fra XML
Versjon 1
Løsningen er basert på etableringen av et XmlDocument:
String xmlsource =
"http://www.it.hiof.no/~borres/commondata/olympiade/all_results.xml";
XmlDocument doc=null;
Data lastes og listeboksen med oversikt over olympiader fylles opp:
private void buttonLoad_Click(object sender, EventArgs e)
{
doc = new XmlDocument();
listBoxOlymp.Items.Clear();
try
{
doc.Load(xmlsource);
labelMsg.Text = "Loaded";
XmlNodeList list =
doc.GetElementsByTagName("OlympicGame");
foreach (XmlElement nod in list)
listBoxOlymp.Items.Add(new connect(nod));
}
catch (Exception ex)
{
labelMsg.Text = ex.Message;
}
}
Her er det valgt å lage en egen klasse, connect, som hjelper oss å kople olymiadens navn til XmlElementet som representerer en olympiade. Denne klassen er slik:
// to connect an XMLElement to a listentry
class connect
{
XmlElement elt;
public connect(XmlElement elt)
{this.elt = elt;}
public override string ToString()
{return elt.GetAttribute("place");}
public XmlElement Elt{get{return elt;}}
}
Når brukeren klikker i olympiadelist blir jobben å finne alle deltagerne på 100m i den olympiaden.
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// walking the tree, level by level
listBoxAthlets.Items.Clear();
connect cnt = (connect)listBoxOlymp.SelectedItem;
XmlElement elt = cnt.Elt;
XmlNodeList list = elt.GetElementsByTagName("event");
foreach (XmlElement evelt in list)
{
if (evelt.GetAttribute("dist") == "100m")
{
XmlNodeList atlist = evelt.GetElementsByTagName("athlet");
foreach (XmlElement at in atlist)
listBoxAthlets.Items.Add(at.GetElementsByTagName("name")[0].InnerText);
}
}
}
Alternativt kan vi bruke XPATH til å finne de aktuelle løperne.
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// using xpath
listBoxAthlets.Items.Clear();
connect cnt = (connect)listBoxOlymp.SelectedItem;
XmlElement elt = cnt.Elt;
XmlNodeList list =elt.SelectNodes("event[@dist='100m']/athlet");
foreach (XmlElement at in list)
listBoxAthlets.Items.Add(at.GetElementsByTagName("name")[0].InnerText);
}
Versjon 2
I denne versjonen baserer vi oss på at det kun har vært en olympiade på hvert sted. Det vil si at "place"-attributten entydig identifiserer en olympiade. Med dette utgangspunktet kan vi legge bare olypiade-stedet i lista og så bruke XPATH til å finne 100m-finalistene.
Etableringen av olymiadelista blir slik, uten noe connect-objekt:
private void buttonLoad_Click(object sender, EventArgs e)
{
doc = new XmlDocument();
listBoxOlympiade.Items.Clear();
try
{
doc.Load(xmlsource);
labelMsg.Text = "Loaded";
XmlNodeList list =
doc.SelectNodes("//OlympicGame");
foreach (XmlElement nod in list)
listBoxOlympiade.Items.Add(nod.GetAttribute("place"));
}
catch (Exception ex)
{
labelMsg.Text = ex.Message;
}
}
Utvalg av 100m-finalister blir slik:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox100m.Items.Clear();
String place=(string)listBoxOlympiade.SelectedItem;
String myXpath =
String.Format(
"//OlympicGame[@place='{0}']/event[@dist='100m']/athlet/name",
place
);
try
{
XmlNodeList list = doc.SelectNodes(myXpath);
foreach (XmlElement at in list)
listBox100m.Items.Add(at.InnerText);
}
catch (Exception ex)
{
labelMsg.Text = ex.Message;
}
}
versjon 3
Vi snur problemet slik at vi begynner med en liste av sprintere som har deltatt i en av de aktuelle olympiadene, for så å finne ut hvor vedkommende har deltatt.
Etableringen av personlista blir slik:
private void buttonLoad_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
doc = new XmlDocument();
try
{
doc.Load(xmlsource);
// fill the listbox with names
XmlNodeList personer = doc.SelectNodes("//name");
foreach(XmlNode p in personer)
{
String n=p.InnerText;
if (!listBox1.Items.Contains(n))
listBox1.Items.Add(n);
}
labelMsg.Text = "loaded";
}
catch (Exception ex)
{
labelMsg.Text = ex.Message;
}
}
Når vi skal velge fra lista kan vi bruke DOM-programmering:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
String n = (string)listBox1.SelectedItem;
textBoxWhat.Text = n + "\r\n";
XmlNodeList deltagelse =
doc.SelectNodes(String.Format("//athlet[name='{0}']",n));
foreach (XmlNode d in deltagelse)
{
String ovelse =
((XmlElement)d.ParentNode).
GetAttribute("dist");
String olymp =
((XmlElement)d.ParentNode.ParentNode).
GetAttribute("place");
textBoxWhat.Text +=
String.Format("deltok på {0} i {1}\r\n",ovelse,olymp);
}
}
eller vi kan bruke XPATH
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
String n = (string)listBox1.SelectedItem;
textBoxWhat.Text = n + "\r\n";
XmlNodeList deltagelse =
doc.SelectNodes(String.Format("//athlet[name='{0}']", n));
foreach (XmlNode d in deltagelse)
{
String ovelse =
((XmlElement)d.SelectSingleNode("..")).
GetAttribute("dist");
String olymp =
((XmlElement)d.SelectSingleNode("../..")).
GetAttribute("place");
textBoxWhat.Text +=
String.Format("deltok på {0} i {1}\r\n", ovelse, olymp);
}
}





