1

I'm having some problems getting a node of XML document in C#

I need to make a program that enables the user to edit the <LimitValue> of each <ControlItem>.

I have already tried to get a node with GetElementById but it always return null and I can't understand why.

This is my xml document:

<?xml version="1.0" encoding="utf-8"?>
<GradeLimits GradeName="1.0305" GradeDescription="P235G1TH (St35.8)" Norm="Trafilspec" BaseElement="Fe">
  <ControlItems>
    <ControlItem Name="C" DisplayUnit="%" Impurity="False">
      <LimitValue Type="UpperWarningLimit" Kind="Absolute" Unit="%">0.17000000178813934</LimitValue>
      <LimitValue Type="UpperAcceptanceLimit" Kind="Absolute" Unit="%">0.18000000715255737</LimitValue>
    </ControlItem>
    <ControlItem Name="Si" DisplayUnit="%" Impurity="False">
      <LimitValue Type="UpperWarningLimit" Kind="Absolute" Unit="%">0.34999999403953552</LimitValue>
      <LimitValue Type="UpperAcceptanceLimit" Kind="Absolute" Unit="%">0.37000000476837158</LimitValue>
    </ControlItem>
    <ControlItem Name="Mn" DisplayUnit="%" Impurity="False">
      <LimitValue Type="LowerWarningLimit" Kind="Absolute" Unit="%">0.40000000596046448</LimitValue>
      <LimitValue Type="UpperWarningLimit" Kind="Absolute" Unit="%">0.800000011920929</LimitValue>
      <LimitValue Type="LowerAcceptanceLimit" Kind="Absolute" Unit="%">0.37999999523162842</LimitValue>
      <LimitValue Type="UpperAcceptanceLimit" Kind="Absolute" Unit="%">0.8399999737739563</LimitValue>
    </ControlItem>
    <ControlItem Name="P" DisplayUnit="%" Impurity="False">
      <LimitValue Type="UpperWarningLimit" Kind="Absolute" Unit="%">0.039999999105930328</LimitValue>
      <LimitValue Type="UpperAcceptanceLimit" Kind="Absolute" Unit="%">0.05000000074505806</LimitValue>
    </ControlItem>
    <ControlItem Name="S" DisplayUnit="%" Impurity="False">
      <LimitValue Type="UpperWarningLimit" Kind="Absolute" Unit="%">0.039999999105930328</LimitValue>
      <LimitValue Type="UpperAcceptanceLimit" Kind="Absolute" Unit="%">0.05000000074505806</LimitValue>
    </ControlItem>
  </ControlItems>
</GradeLimits>

I've tried to do this too, but it doesn't work:

     foreach (FileInfo file in Files)
            {
                count1++;
                if (count1 == select) {         
                    namefile = Files[select].Name;
                    doc.Load(@"C:\Users\lab\Desktop\copy\spectro\"+namefile);

                    var node = doc.SelectSingleNode("//*[@Name='C']");
                    Console.WriteLine(node);

                }
            }

For example in this case the <ControlItem Name="C"> has <LimitValue Type="UpperWarningLimit" ...>0.17000</limitvalue>, and I want to give the user the possibility of setting the value that they want.

I can't read the node and I don't know how to set this value either.

1 Answer 1

1

Here is a code sample that will allow you to get the child node:

        XmlDocument doc = new XmlDocument();
        doc.Load(@"C:\Source\Testing\XML\doc.xml");

        var nodeControlItem = doc.SelectSingleNode("//*[@Name='C']");

        var nodeLimitValue = nodeControlItem.SelectSingleNode("//*[@Type='UpperWarningLimit']");

        Console.Write(nodeLimitValue.InnerText);

Your program can then use the same "nodeLimitValue.InnerText" property to update the value in the XML. (Remember to save your XML document when you are done making changes.

You were on the right track with your code, but you were only getting the ControlItem node, and not its child node (LimitValue). From your ControlItem node, you can use SelectSingleNode again to select his children nodes, thus being able to extract or manipulate the value of the LimitValue node.

Hope this helps.

EDIT:

Here is an expanded code sample to help you a bit more:

        XmlDocument doc = new XmlDocument();
        doc.Load(@"C:\Source\Testing\XML\doc.xml");

        // This line will select "the first node" in the XML Document with attribute Name="C"
        XmlNode nodeControlItem = doc.SelectSingleNode("//*[@Name='C']");

        // Alternatively, you can accomplish the same thing by iterating through all of the ControlItem nodes to find the one you want:
        foreach (XmlNode node in doc.SelectNodes("/GradeLimits/ControlItems/ControlItem"))
        {
            if (node.Attributes.GetNamedItem("Name").Value == "C")
            {
                nodeControlItem = node;
                break;
            }
        }

        //Now that you have your "C" ControlItem, you can find a child node with Type="UpperWarningLimit"
        XmlNode nodeLimitValue = nodeControlItem.SelectSingleNode("//*[@Type='UpperWarningLimit']");

        //Alternatively, you can accomplish the same thing by iterating through all of the ChildNodes of the ControlItem to find the one you want:
        foreach (XmlNode childNode in nodeControlItem.ChildNodes)
        {
            if (childNode.Attributes.GetNamedItem("Type").Value == "UpperWarningLimit")
            {
                nodeLimitValue = childNode;
                break;
            }
        }

        //Or, another is to iterating through all of the LimitValue child nodes of the ControlItem to find the one you want:
        foreach (XmlNode childNode in nodeControlItem.SelectNodes("./LimitValue"))
        {
            if (childNode.Attributes.GetNamedItem("Type").Value == "UpperWarningLimit")
            {
                nodeLimitValue = childNode;
                break;
            }
        }

        Console.Write(nodeLimitValue.Value);

        // Modify the value of the node
        nodeLimitValue.Value = "0.00000";

        Console.Write(nodeLimitValue.Value);

        // Save the XML document back to disk
        doc.Save(@"C:\Source\Testing\XML\doc.xml");

For more details, you should read about XPath syntax.

Sign up to request clarification or add additional context in comments.

2 Comments

I should also point out that their are some useful properties in the XmlNode like FirstChild and LastChild that may be useful to you, or the ChildNodes property that would allow you to iterate through all child nodes (since you have different sets of child nodes under each ControlItem.
sorry but i'm quite you with handling xml, how can i iterate on all ControlItems to find the one that i need, for example the controlitem with attribute Name="S"?

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.