Home

XML Example Application: Road System Database

   

Introduction

The US federal government, the states governments, and local municipalities are in charge of creating and manging roads. Tithout going through all the details, this is a sample database in that area of work.

 

Code File: RoadNew.cs

module NewRoad
open System
open System.IO
open System.Xml
open System.Drawing
open System.Windows.Forms

let roadNew : Form = new Form(ShowInTaskbar = false,
                              Text = "Road System Database - New Road",
                              MaximizeBox = false, MinimizeBox = false,
                              FormBorderStyle = FormBorderStyle.FixedDialog,
                              ClientSize = new System.Drawing.Size(517, 189),
                              StartPosition = FormStartPosition.CenterScreen)

// Road Name
roadNew.Controls.Add(new Label(AutoSize = true, Text = "Road Name:",
                               Location = new System.Drawing.Point(23, 21)))
let txtRoadName = new TextBox(Width = 100, Location = new Point(96, 18))
roadNew.Controls.Add txtRoadName

// Road Type
roadNew.Controls.Add(new Label(AutoSize = true, Text = "Road Type:",
                               Location = new System.Drawing.Point(23, 51)))

let cbxRoadTypes = new ComboBox(Width = 100, Location = new Point(96, 48))
roadNew.Controls.Add cbxRoadTypes

// Distance
roadNew.Controls.Add(new Label(AutoSize = true, Text = "Distance:",
                               Location = new System.Drawing.Point(23, 82)))
let txtDistance = new TextBox(TextAlign = HorizontalAlignment.Right,
                              Width = 100, Location = new Point(96, 79))
roadNew.Controls.Add txtDistance

// Location
roadNew.Controls.Add(new Label(AutoSize = true, Text = "Location:",
                               Location = new System.Drawing.Point(23, 112)))
let txtLocation = new TextBox(Width = 400, Location = new Point(96, 109))
roadNew.Controls.Add txtLocation

// OK
let btnOK = new Button(Location = new Point(327, 147),
                       Text = "OK", DialogResult = DialogResult.OK)
roadNew.AcceptButton <- btnOK
roadNew.Controls.Add btnOK

// Cancel
let btnCancel = new Button(Location = new Point(419, 147),
                           Text = "Cancel", DialogResult = DialogResult.Cancel)
roadNew.CancelButton <- btnCancel
roadNew.Controls.Add btnCancel

let roadNewLoad e =
    let xdRoads : XmlDocument = new XmlDocument()
    let strRoadsFile : string = @"C:\Road Database\Roads.xml"

    if File.Exists strRoadsFile then
        cbxRoadTypes.Items.Clear()

        use fsRoads : FileStream = new FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
        xdRoads.Load fsRoads
        
        let xnlRoads : XmlNodeList = xdRoads.DocumentElement.ChildNodes

        for xnRoad : XmlNode in xnlRoads do
            if cbxRoadTypes.Items.Contains(xnRoad.FirstChild.NextSibling.InnerText) = false then
                cbxRoadTypes.Items.Add xnRoad.FirstChild.NextSibling.InnerText |> ignore
        fsRoads.Close()

roadNew.Load.Add roadNewLoad

Code File: IntersectionNew.cs

module NewIntersection
open System
open System.IO
open System.Xml
open System.Drawing
open System.Windows.Forms

let intersectionNew : Form = new Form(ShowInTaskbar = false,
                                      MaximizeBox = false, MinimizeBox = false,
                                      FormBorderStyle = FormBorderStyle.FixedDialog,
                                      ClientSize = new System.Drawing.Size(558, 162),
                                      StartPosition = FormStartPosition.CenterScreen,
                                      Text = "Road System Database - New Intersection")

// Existing Road
intersectionNew.Controls.Add(new Label(AutoSize = true, Text = "Existing Road:",
                                       Location = new System.Drawing.Point(22, 22)))
let cbxExistingRoads = new ComboBox(Width = 126, Location = new Point(117, 19),
                                    DropDownStyle = ComboBoxStyle.DropDownList)
intersectionNew.Controls.Add cbxExistingRoads

// Intersectin Road
intersectionNew.Controls.Add(new Label(AutoSize = true, Text = "Intersectin Road:",
                                       Location = new System.Drawing.Point(22, 54)))
let txtIntersectingRoad = new TextBox(Width = 126, Location = new Point(117, 51))
intersectionNew.Controls.Add txtIntersectingRoad

// In Or Near
intersectionNew.Controls.Add(new Label(AutoSize = true, Text = "In Or Near:",
                                       Location = new System.Drawing.Point(22, 85)))
let txtInOrNear = new TextBox(Width = 417, Location = new Point(117, 82))
intersectionNew.Controls.Add txtInOrNear

// OK
let btnOK = new Button(Location = new Point(367, 118),
                       Text = "OK", DialogResult = DialogResult.OK)
intersectionNew.AcceptButton <- btnOK
intersectionNew.Controls.Add btnOK

// Cancel
let btnCancel = new Button(Location = new Point(459, 118),
                           Text = "Cancel", DialogResult = DialogResult.Cancel)
intersectionNew.CancelButton <- btnCancel
intersectionNew.Controls.Add btnCancel

let intersectionNewLoad e =
    let xdRoads : XmlDocument = new XmlDocument()
    let strRoadsFile : string = @"C:\Road Database\Roads.xml"

    if File.Exists(strRoadsFile) then
        cbxExistingRoads.Items.Clear()

        use fsRoads : FileStream = new FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
        xdRoads.Load fsRoads

        let xnlRoads : XmlNodeList = xdRoads.DocumentElement.ChildNodes;

        for xnRoad : XmlNode in xnlRoads do
            if cbxExistingRoads.Items.Contains(xnRoad.FirstChild.InnerText) = false then
                cbxExistingRoads.Items.Add xnRoad.FirstChild.InnerText |> ignore
        fsRoads.Close()

intersectionNew.Load.Add intersectionNewLoad

Code File: Program.cs

open System
open System.IO
open System.Xml
open System.Drawing
open System.Windows.Forms

open NewRoad
open NewIntersection

let roadDatabase = new Form(ClientSize = new System.Drawing.Size(727, 678),
                            StartPosition = FormStartPosition.CenterScreen,
                            MaximizeBox = false, Text = "Road System Database")

// List View: List of Road
let lvwRoads  = new ListView(GridLines = true, View = View.Details,
                             Size = new System.Drawing.Size(702, 295),
                             FullRowSelect = true, Location = new Point(12, 14),
                             Anchor = (AnchorStyles.Top ||| AnchorStyles.Bottom ||| AnchorStyles.Left ||| AnchorStyles.Right))

let mutable colRoad = lvwRoads .Columns.Add("Road Name", 70)
colRoad <- lvwRoads.Columns.Add("Road Type", 85, HorizontalAlignment.Center)
colRoad <- lvwRoads.Columns.Add("Distance(Miles)", 85, HorizontalAlignment.Right)
colRoad <- lvwRoads.Columns.Add("Location", 445)
roadDatabase.Controls.Add lvwRoads

// List View: Intersections
let lvwIntersections  = new ListView(GridLines = true, View = View.Details,
                                     Size = new System.Drawing.Size(375, 332),
                                     FullRowSelect = true, Location = new Point(142, 325),
                                     Anchor = (AnchorStyles.Bottom ||| AnchorStyles.Left ||| AnchorStyles.Right))

colRoad <- lvwIntersections.Columns.Add("Road", 50)
colRoad <- lvwIntersections.Columns.Add("Intersects With", 120)
colRoad <- lvwIntersections.Columns.Add("In/Near", 180)
roadDatabase.Controls.Add lvwIntersections

// Button: New Intersection
let btnNewRoad = new Button(Location = new System.Drawing.Point(535, 535),
                          Text = "New Road", Size = new System.Drawing.Size(145, 36),
                          Anchor = (AnchorStyles.Bottom ||| AnchorStyles.Right))
roadDatabase.Controls.Add btnNewRoad

// Button: New Road
let btnNewIntersection = new Button(Location = new System.Drawing.Point(535, 578),
                          Text = "New Intersection", Size = new System.Drawing.Size(145, 36),
                          Anchor = (AnchorStyles.Bottom ||| AnchorStyles.Right))
roadDatabase.Controls.Add btnNewIntersection

// Button: Close
let btnClose = new Button(Location = new System.Drawing.Point(535, 620),
                          Text = "Close", Size = new System.Drawing.Size(145, 36),
                          Anchor = (AnchorStyles.Bottom ||| AnchorStyles.Right))
roadDatabase.Controls.Add btnClose

let showRoads() =
    let xdRoads : XmlDocument = new XmlDocument()
    let strRoadsFile : string = @"C:\Road Database\Roads.xml"

    if File.Exists(strRoadsFile) then
        lvwRoads.Items.Clear()
            
        use fsRoads : FileStream = new FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
        
        xdRoads.Load fsRoads
        let xeRoad : XmlElement = xdRoads.DocumentElement
        let xnlRoads : XmlNodeList = xeRoad.ChildNodes

        for xnRoad : XmlNode in xnlRoads do
            let lviRoad = new ListViewItem(xnRoad.FirstChild.InnerText) // Road Name

            lviRoad.SubItems.Add xnRoad.FirstChild.NextSibling.InnerText |> ignore // Road Type
            lviRoad.SubItems.Add xnRoad.FirstChild.NextSibling.NextSibling.InnerText |> ignore // Distance
            lviRoad.SubItems.Add xnRoad.FirstChild.NextSibling.NextSibling.NextSibling.InnerText |> ignore // Location

            lvwRoads.Items.Add lviRoad |> ignore
        fsRoads.Close()

let roadDatabaseLoad e =
    Directory.CreateDirectory @"C:\Road Database" |> ignore
    showRoads()
roadDatabase.Load.Add roadDatabaseLoad

let lvwRoadsItemSelectionChanged(e : ListViewItemSelectionChangedEventArgs) =
    let xdRoads : XmlDocument = new XmlDocument()
    let roadSelected : string = e.Item.SubItems.[0].Text
    let strRoadsFile : string = @"C:\Road Database\Roads.xml"

    if File.Exists(strRoadsFile) then
        lvwIntersections.Items.Clear()

        use fsRoads : FileStream = new FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
        xdRoads.Load fsRoads

        let xeRoad : XmlElement = xdRoads.DocumentElement
        let xnlRoads : XmlNodeList = xdRoads.GetElementsByTagName "road-name"

        for xnRoad : XmlNode in xnlRoads do
            if xnRoad.InnerText = roadSelected then
                let xnlIntersections : XmlNodeList = xnRoad.NextSibling.NextSibling.NextSibling.NextSibling.ChildNodes

                for i in 0 .. xnlIntersections.Count - 1 do
                    let lviIntersection : ListViewItem = new ListViewItem(roadSelected) // Selected Road
                    
                    lviIntersection.SubItems.Add xnlIntersections.[i].ChildNodes.[0].InnerText |> ignore // Intersects With
                    lviIntersection.SubItems.Add xnlIntersections.[i].ChildNodes.[1].InnerText |> ignore // In or Near

                    lvwIntersections.Items.Add lviIntersection |> ignore
        fsRoads.Close()
lvwRoads.ItemSelectionChanged.Add lvwRoadsItemSelectionChanged

let btnNewRoadClick e =
    let xdRoads : XmlDocument = new XmlDocument()
    let strRoadsFile : string = @"C:\Road Database\Roads.xml"

    if roadNew.ShowDialog() = DialogResult.OK then
        if File.Exists(strRoadsFile) = false then
            xdRoads.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                            "<roads />")

            use fsRoads = new FileStream(strRoadsFile, FileMode.CreateNew, FileAccess.Write)
            xdRoads.Save fsRoads
            fsRoads.Close()

        use fsRoads = new FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
        xdRoads.Load fsRoads
        fsRoads.Close()
        
        use fsRoads = new FileStream(strRoadsFile, FileMode.OpenOrCreate, FileAccess.Write)
        
        let xeRoad : XmlElement = xdRoads.CreateElement "road"
        xeRoad.InnerXml <- "<road-name>" + NewRoad.txtRoadName.Text + "</road-name>" +
                           "<road-type>" + NewRoad.cbxRoadTypes.Text + "</road-type>" +
                           "<distance>" + NewRoad.txtDistance.Text + "</distance>" +
                           "<location>" + NewRoad.txtLocation.Text + "</location>" +
                           "<intersections />"
        let xnRoad = xdRoads.DocumentElement.AppendChild xeRoad
        xdRoads.Save fsRoads
        fsRoads.Close()

        NewRoad.txtRoadName.Text <- ""
        NewRoad.cbxRoadTypes.Text <- ""
        NewRoad.txtDistance.Text <- ""
        NewRoad.txtLocation.Text <- ""

    showRoads()

btnNewRoad.Click.Add btnNewRoadClick

let btnNewIntersectionClick e =
    let xdRoads : XmlDocument = new XmlDocument()
    let strRoadsFile : string = @"C:\Road Database\Roads.xml"

    if intersectionNew.ShowDialog() = DialogResult.OK then
        if String.IsNullOrEmpty(NewIntersection.cbxExistingRoads.Text) then
            MessageBox.Show("You must select the road whose intersection(s) you want to specify.",
                                "Road System Database", MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore
        elif String.IsNullOrEmpty(NewIntersection.txtIntersectingRoad.Text) then
            MessageBox.Show("You must enter the name of a road that intersects with the selected road.",
                            "Road System Database", MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore
        else
            if File.Exists(strRoadsFile) then
                use fsRoads : FileStream = new FileStream(strRoadsFile, FileMode.Open, FileAccess.Read)
                xdRoads.Load fsRoads
                fsRoads.Close()
                
                let xnlRoads : XmlNodeList = xdRoads.GetElementsByTagName "road-name"

                use fsRoads : FileStream = new FileStream(strRoadsFile, FileMode.OpenOrCreate, FileAccess.Write)
                
                for xnIntersection : XmlNode in xnlRoads do
                    if xnIntersection.InnerText = NewIntersection.cbxExistingRoads.Text then
                        let xeIntersection : XmlElement = xdRoads.CreateElement "intersection"

                        xeIntersection.InnerXml <- "<intersecting>" + NewIntersection.txtIntersectingRoad.Text + "</intersecting>" +
                                                   "<in-near>" + NewIntersection.txtInOrNear.Text + "</in-near>";
                        let xnCreated = xnIntersection.NextSibling.NextSibling.NextSibling.NextSibling.AppendChild xeIntersection
                        xdRoads.Save fsRoads

                        NewIntersection.txtIntersectingRoad.Text <- ""
                        NewIntersection.txtInOrNear.Text <- ""
                fsRoads.Close()

    showRoads()
btnNewIntersection.Click.Add btnNewIntersectionClick

let btnCloseClick e = roadDatabase.Close()
btnClose.Click.Add btnCloseClick

[<EntryPoint>]
let main argv = 
    Application.Run roadDatabase
    0

An examples of running the program would produce:

Locating an Element Using a Tag Name

Locating an Element Using a Tag Name

Locating an Element Using a Tag Name

Locating an Element Using a Tag Name

 
   
     
 

Previous Copyright © 2015 FunctionX Next