kyle_13
kyle_13

Reputation: 1233

Accessing a child node by name of an XML document using C#

I have a situation which an XML document contained something similar to the following, but then the order of the "Block" elements was changed, and in an application, I was accessing the value of the in by using GetElementsByTagName("Amount")[0].InnerText, as it was the first occurrence of "Amount". Then the order of the "Blocks" changed, and the "Amount" returned by the GetElementsByTagName was still the first occurrence, but I want the "Amount" in "Block1" to always be returned. How do I accomplish this in C#?

Before:

<Response xmlns="testsite.com/schema/TestService/2015-01-01">
  <Block1>
     <Amount>$5.00</Amount>
  </Block1>
  <Block2>
     <Amount>$0.00</Amount>
  </Block2>
  <Block3>
     <Amount>$0.00</Amount>
  </Block3>
</Response>

After:

<Response xmlns="testsite.com/schema/TestService/2015-01-01">
  <Block2>
     <Amount>$0.00</Amount>
  </Block2>
  <Block3>
     <Amount>$0.00</Amount>
  </Block3>
  <Block1>
     <Amount>$5.00</Amount>
  </Block1>
</Response>

C#:

XmlDocument doc = new XmlDocument();
doc.LoadXml(response);

string amount = doc.GetElementsByTagName("Amount")[0].InnerText;

Upvotes: 0

Views: 449

Answers (3)

dotnetom
dotnetom

Reputation: 24901

You can use method SelectSingleNode and XPath expression to access the data that you need. You also need to use namespace manager and import correct namespace:

var namespaceManager= new XmlNamespaceManager(doc.NameTable);
namespaceManager.AddNamespace("a", "testsite.com/schema/TestService/2015-01-01");

var xmlNode = doc.SelectSingleNode("/a:Response/a:Block1/a:Amount", namespaceManager);
var value = node.InnerText;    // prints $5.00

Such code would find you correct value regardless of where Block1 is - first, second or third element. The method SelectSingleNode returns first node that matches an expression, so if you have more than one Block1 element in your XML then the results might be not what you expect

Upvotes: 0

Eser
Eser

Reputation: 12546

however, in my root element I have something like <Response xmlns="testsite.com/schema/TestService/2015-01-01">

It is the default xmlnamespece of your xml. With the new info you provided

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("ns", "testsite.com/schema/TestService/2015-01-01");

var value = doc.SelectSingleNode("/ns:Response/ns:Block1/ns:Amount", mgr).InnerText;

Upvotes: 2

cyi
cyi

Reputation: 96

Start with System.Xml.Linq; You'll want to load your xml file and then parse your document. For example,

var doc = XDocument.Load("file.xml");
IEnumerable<XElement> elements = doc.Descendants(tagNameHere);

And if you want to create a list of those descendants, you can access those elements by doing something like this:

List<string> myElements = new List<string>();
XElement element = elements.ElementAt(0);
myElements.Add(element.Value);

This is just to get you started. I suggest you read here:

https://msdn.microsoft.com/en-us/library/system.xml.linq(v=vs.110).aspx

Upvotes: 0

Related Questions