1

In my application I want to get the value of an xml node display in a textbox if the user type in a number in another textbox (for example: User type in textbox1 the number "123". The application should check the xml if "123" exists and then gets the value of the other nodes). But the xml file isn't fixed. It's created by the application itself (what user types in textboxes).

After hours I still don't get it. It sounds very simple (and I be sure for most of you it is) but I'm a big newbie in c#. So I googled a lot and finally found SelectSingleNode and SelectNodes. First I tried this code:

private void txtKNrNew_Leave(object sender, EventArgs e)
{
    XDocument xdoc = XDocument.Load(path + "\\save.xml");
    int CustNos;

    if (Int32.TryParse(txtKNrNew.Text, out CustNos))
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(path + "\\save.xml");

        var xmlNodeExist = "Buchhaltung/Customers/CustNo";
        var CustNoExist = xdoc.XPathSelectElements(xmlNodeExist).FirstOrDefault(x => (int)x == CustNos);

        var SurnameNode = xmlDoc.SelectSingleNode("Buchhaltung/Customers/Surname");
        var ForenameNode = xmlDoc.SelectSingleNode("Buchhaltung/Customers/Forename");
        string surname = SurnameNode.InnerText;
        string forename = ForenameNode.InnerText;

        if (CustNoExist != null)
        {
            txtSurnameNew.Text = surname;
            txtForenameNew.Text = forename;
        }
    }
}

This always returns me the values of the first xml nodes (Here: "Stuff" and "Thing". At the end you can see the XML file). So I tried using SelectNodes:

private void txtKNrNew_Leave(object sender, EventArgs e)
{
    XDocument xdoc = XDocument.Load(path + "\\save.xml");
    int CustNos;

    if (Int32.TryParse(txtKNrNew.Text, out CustNos))
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(path + "\\save.xml");

        var xmlNodeExist = "Buchhaltung/Customers/CustNo";
        var CustNoExist = xdoc.XPathSelectElements(xmlNodeExist).FirstOrDefault(x => (int)x == CustNos);

        var SurnameNode = xmlDoc.SelectNodes("Buchhaltung/Customers/Surname");
        var ForenameNode = xmlDoc.SelectNodes("Buchhaltung/Customers/Forename");
        string surname = SurnameNode[0].InnerText;
        string forename = ForenameNode[0].InnerText;

        if (CustNoExist != null)
        {
            txtSurnameNew.Text = surname;
            txtForenameNew.Text = forename;
        }
    }
}

This returns me the same as the other one. I know because I use [0]. So the number in [] should not be fixed. But is there a way to do this not fixed? And which way is the better way to do this? How can I get the values correctly like I want?

Can someone please help me or give me a hint?

Thanks, Tyler

PS: And here you can see my generated XML file:

<Buchhaltung>
  <Customers>
    <CustNo>123</CustNo>
    <Surname>Stuff</Surname>
    <Forename>Thing</Forename>
    <Addr>Addr</Addr>
    <Zip>Zip</Zip>
    <Place>Place</Place>
    <Phone>Phone</Phone>
    <Mail>Mail</Mail>
  </Customers>
  <Customers>
    <CustNo>137</CustNo>
    <Surname>Other</Surname>
    <Forename>Name</Forename>
    <Addr>Address</Addr>
    <Zip>12345</Zip>
    <Place>New York</Place>
    <Phone>1234567890</Phone>
    <Mail>[email protected]</Mail>
  </Customers>
</Buchhaltung>

3 Answers 3

2

You can use the following XPath-expression:

var expression = String.Format("//Customers[CustNo/text() = {0}]/", CustNos);

var SurnameNode = xmlDoc.SelectNodes(expression + "Surname");
var ForenameNode = xmlDoc.SelectNodes(expression +"Forename");
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. Can you explain me the first line? I don't get it
It's the XPaht expression that says: Find any Customers element (//Customers) that contains a sub-element CustNo that has the value == to CustNo variable ([CustNo/text() = 123]). Then I concatenate the "Surname" and "Forename" to get the correct subelement of the found Customers-element. There was an error in my original post but I have corrected it now.
1

You can use LINQ2XML

XDocument doc=XDocument.Load(path);
var node=doc.Elements("Customers")
            .SingleOrDefault(x=>x.Element("CustNo").Value==CustNos.ToString());
if(node!=null)
{
   txtSurnameNew.Text=node.Element("Surname").Value;
   txtForenameNew.Text=node.Element("Forename").Value;
}

1 Comment

Thanks for the answer. If I use this code, I got this error message at txtSurnameNew.Text=: the object reference not set to an instance of an object
0

How about that:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(path + "\\save.xml");

var xmlNodeExist = "Buchhaltung/Customers/CustNo";
var CustNoExist = xdoc.XPathSelectElements(xmlNodeExist).FirstOrDefault(x => (int)x == CustNos);

var SurnameNode = xmlDoc.SelectNodes("Buchhaltung/Customers/Surname");
var ForenameNode = xmlDoc.SelectNodes("Buchhaltung/Customers/Forename");

if (CustNoExist != null)
{
    foreach(XmlNode xn in SurnameNode)
    {
        txtSurnameNew.Text += xn.InnerText + Environment.Newline;
    }

    foreach(XmlNode xn in ForenameNode)
    {
        txtForenameNew.Text += xn.InnerText + Environment.Newline;
    }
}

Hope that will help you. Toby

3 Comments

That does not work because I can't use Newline and is xdoc and xmlDoc at the same time and xdoc is not defined
then you could use: foreach(XmlNode xn in SurnameNode) { txtSurnameNew.Text += xn.InnerText + ", "; } foreach(XmlNode xn in ForenameNode) { txtForenameNew.Text += xn.InnerText + ", "; } The "xdoc" comes from your code :)
Mh, that also does not work :/ I get this error: reference not set to an instance of an object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.