Comparing comboBox.Slectedvalue with XML file node value using Xpath in C#

This is part of my XML file, and I have on my c# form a combo box that contains the names of the devices form the xml file which I've put there by using xpath navigator, plus a numeric up down, and finally a button I called Buy. what i wanna do is when I hit the button Buy I want the QUANTITY node value of the DEVICE node whos NAME node value equals to the combo box SelectedValue to increase by the number of the numeric up down value. In other words how can I select the QUANTITY node of a DEVICE element that has its NAME equal to the name in the combo box and the increase it by the value of the numeric up down of course using C#.

<INVENTORY>
<DEVICE ID="1">
    <NAME>Air Steerable Bagless Upright</NAME>
    <BRAND>Hoover</BRAND>
    <MODEL>UH72400</MODEL>
    <QUANTITY>23</QUANTITY>
    <BUYING_PRICE>189.99</BUYING_PRICE>
    <SELLING_PRICE>229.99</SELLING_PRICE>
</DEVICE>
<DEVICE ID="2">
    <NAME>Quietforce Bagged Canister</NAME>
    <BRAND>Hoover</BRAND>
    <MODEL>SH30050</MODEL>
    <QUANTITY>18</QUANTITY>
    <BUYING_PRICE>299.99</BUYING_PRICE>
    <SELLING_PRICE>334.99</SELLING_PRICE>
</DEVICE>
<DEVICE ID="3">
    <NAME>Corded Cyclonic Stick Vacuum</NAME>
    <BRAND>Hoover</BRAND>
    <MODEL>SH20030</MODEL>
    <QUANTITY>21</QUANTITY>
    <BUYING_PRICE>79.99</BUYING_PRICE>
    <SELLING_PRICE>109.99</SELLING_PRICE>
</DEVICE>

Answers


Well, I think an iterating approach is easier to understand in this case. What we want to do is find an XmlElement, that has a specified Name-element with the desired content.

It helps to think of the XmlDocument as a tree. This tree has different nodes. The topmost node is the Inventory. TheInventory`-Node has (in this case) three device subnodes. Every device subnode has subnodes as well (Name, Brand, etc.). With that in mind its easy to find the quantity. We iterate over the tree and check if the name element matches the search string. If it does, we get the value of the quantity element. Here is a small Console application illustrating a possible solution. Keep in mind that this solution can cause exceptions if the XML is not well-formed (for instance the NAME element is missing).

    static void Main(string[] args)
    {
        XmlDocument xdoc = new XmlDocument();

        string searchName = "Quietforce Bagged Canister";

        xdoc.LoadXml(@"<INVENTORY>
                        <DEVICE ID='1'>
                            <NAME>Air Steerable Bagless Upright</NAME>
                            <BRAND>Hoover</BRAND>
                            <MODEL>UH72400</MODEL>
                            <QUANTITY>23</QUANTITY>
                            <BUYING_PRICE>189.99</BUYING_PRICE>
                            <SELLING_PRICE>229.99</SELLING_PRICE>
                        </DEVICE>
                        <DEVICE ID='2'>
                            <NAME>Quietforce Bagged Canister</NAME>
                            <BRAND>Hoover</BRAND>
                            <MODEL>SH30050</MODEL>
                            <QUANTITY>18</QUANTITY>
                            <BUYING_PRICE>299.99</BUYING_PRICE>
                            <SELLING_PRICE>334.99</SELLING_PRICE>
                        </DEVICE>
                        <DEVICE ID='3'>
                            <NAME>Corded Cyclonic Stick Vacuum</NAME>
                            <BRAND>Hoover</BRAND>
                            <MODEL>SH20030</MODEL>
                            <QUANTITY>21</QUANTITY>
                            <BUYING_PRICE>79.99</BUYING_PRICE>
                            <SELLING_PRICE>109.99</SELLING_PRICE>
                        </DEVICE></INVENTORY>");

        //this is the INVENTORY element. You might need to customize that, in case the INVENTORY is not the root
        XmlNode rootElement = xdoc.FirstChild;

        //-1 means that no mathing item was found.
        int quantity = -1;

        //Here we iterate over every device element
        foreach(XmlNode device in rootElement.ChildNodes)
        {
            //TODO: Validate XML first. Missing Elements can cause exceptions

            //We can access the child elements of the decives with their element name
            if(String.Equals(device["NAME"].InnerText, searchName))
            {
                quantity = Int32.Parse(device["QUANTITY"].InnerText);
                break;
            }
        }

        Console.WriteLine(quantity.ToString());
        Console.ReadLine();
    }

If you prefer a LINQ to SQL approach something like this would work.

public string GetXML()
{
    return @"<root><DEVICE ID=""1"">
                    <NAME>Air Steerable Bagless Upright</NAME>
                    <BRAND>Hoover</BRAND>
                    <MODEL>UH72400</MODEL>
                    <QUANTITY>23</QUANTITY>
                    <BUYING_PRICE>189.99</BUYING_PRICE>
                    <SELLING_PRICE>229.99</SELLING_PRICE>
                </DEVICE>
                <DEVICE ID=""2"">
                    <NAME>Quietforce Bagged Canister</NAME>
                    <BRAND>Hoover</BRAND>
                    <MODEL>SH30050</MODEL>
                    <QUANTITY>18</QUANTITY>
                    <BUYING_PRICE>299.99</BUYING_PRICE>
                    <SELLING_PRICE>334.99</SELLING_PRICE>
                </DEVICE>
                <DEVICE ID=""3"">
                    <NAME>Corded Cyclonic Stick Vacuum</NAME>
                    <BRAND>Hoover</BRAND>
                    <MODEL>SH20030</MODEL>
                    <QUANTITY>21</QUANTITY>
                    <BUYING_PRICE>79.99</BUYING_PRICE>
                    <SELLING_PRICE>109.99</SELLING_PRICE>
                </DEVICE></root>";

}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    ///this would be your up down control

    var xml = XDocument.Parse(GetXML());
    var device = xml.Descendants("DEVICE").Where(d => d.Descendants("NAME").First().Value == "Air Steerable Bagless Upright");
    var quantity = Convert.ToInt16(device.Descendants("QUANTITY").First().Value);
    quantity++;
    device.Descendants("QUANTITY").First().Value = quantity.ToString();
    xml.Save(@"c:\temp\temp.xml");
}

private void button2_Click(object sender, EventArgs e)//Button Buy clicking method
        {
            XmlDocument inventory = new XmlDocument();
            inventory.Load("Inventory.xml");
            string vacuumName = (string)vacuumsBox.SelectedItem;//vacuumBox is a comboBox that contains the vacuums names
            XmlNode rootElement = inventory.FirstChild.NextSibling;//first child is the xml encoding type tag not the root

            int quantity, newQuantity = 0;
            foreach (XmlNode device in rootElement.ChildNodes)
            {
                if (String.Equals(device["NAME"].InnerText, vacuumName))
                {
                    int number = Convert.ToInt32(vacuumsNumber.Value);//vacuumNumber is the name of the numeric up down
                    quantity = Int32.Parse(device["QUANTITY"].InnerText);
                    newQuantity = quantity + number;
                    device["QUANTITY"].InnerText = newQuantity.ToString();//Updating the QUANTITY node value.
                    inventory.Save("Inventory.xml");
                    continue;
                }
            }

Need Your Help

Writing plugins to TortoiseSVN

svn plugins tortoisesvn

Is it possible to write a new plugin to TortoiseSVN?

How to check if page is postback within reserved function pageLoad on ASP.NET AJAX

javascript asp.net-ajax postback lifecycle

I'm looking for a way to check within pageLoad() if this method is raised during load event because of a postback/async postback or because of being loaded and access the first time.