6

I have following XML:

<Loop Name="MasterData">
  <Loop Name="SlaveData">
    <Segment Name="AAA">
      <Node1>hello</Node1>
      <Node2>john</Node2>
      <Node3>hi</Node3>
      <Node4>marry</Node4>
    </Segment>
    <Segment Name="BBB">
      <Node1>00</Node1>
      <Node2> </Node2>
      <Node3>00</Node3>
      <Node4> </Node4>
    </Segment> 
   </Loop>
</Loop>

I have to read value of each Node i.e, Node1, Node2, Node3, Node4 which are under Segment node whose attribute ie Name = "AAA". How can I do this. I am referring following link from stackoverflow but thats not working for me.

How to read attribute value from XmlNode in C#?

I need output like this

Lets I have four sting variables strNode1, strNode2, strNode3, strNode4. I want to store values in above four variables like following

strNode1 = "hello"
strNode2 = "john"
strNode3 = "hi"
strNode4  = "marry"
1
  • 4
    "Not working" isn't an error description. Please show the code you have tried and tell us what the problem is with it. Commented Apr 22, 2013 at 12:30

9 Answers 9

8

You could use XmlDocument to load your xml as an object and then query the specific nodes you want using XPath. Your xpath query (which I can't test right now) would probably look like this.

XmlNodeList xNodes = xmlDocument.SelectNodes("//Segment[@Name = 'AAA']");
Sign up to request clarification or add additional context in comments.

2 Comments

SelectNodes returns an XmlNodeList, not an XmlNode.
you can go one step further in the XPath since OP only wants the innerText using the node() function and the Cast XLinq function. I.e. dom.SelectNodes("//Segment[@Name = 'AAA']/node()").Cast<XmlNode>().Select(n => n.InnerText).ToList()
7

I found a simple solution for my problem

XmlNodeList xnList = doc.SelectNodes("/Loop/Loop/Segment[@Name='AAA']");
          foreach (XmlNode xn in xnList)
          {
              if (xn.HasChildNodes)
              {
                  foreach (XmlNode item in xn.ChildNodes)
                  {
                      Console.WriteLine(item.InnerText);
                  }
              }  
          }

Comments

4

I'd recommend using an XDocument (NB specific filtering based on parent nodes etc omitted):

var document = XDocument.Load(path);
var nodes = document.Descendents().Where(e => e.Name.LocalName.StartsWith("Node"));

Update to include filtering of parent element

var nodes = document.Descendents()
                    .Where(e => e.Atrributes().Any(a => a.Name.localName == "Name" && a.Value == "AAA"))
                    .SelectMany(e => e.Descendents().Where(e => e.Name.LocalName.StartsWith("Node"));
var values = nodes.Select(n => n.Value).ToList(); // This will be a list containing "hello", "john, "hi", "marry"

3 Comments

I have to read Node1,Node2, Node3, Node4 which are under segment whose Name = "AAA". I think your solution will try to read all Node elements
Have you consider the filtering?
Answer now updated to include the filtering and selection of values. NB Very few assumptions are made about the structure of the xml, all elements that are descendents of an element who has a name attribute of "AAA" are eligible, rather than just those that fall under the Loop -> Loop -> Segment hierarchy
3

Assuming you have an XmlDocument you can use XPath like:

XmlNode node = doc.SelectSingleNode("//Segment[@Name='AAA']");

to get the Segment node and then iterate all its children in a loop.

Comments

2

You could use XmlDocument and XPath:

XmlDocument doc = new XmlDocument();
doc.Load(xml);
foreach(XmlNode node in doc.SelectNodes("//Segment[@Name='AAA']/node()"))
{
    string name = node.Name;
    string value = node.innerText;
    // ...
}

1 Comment

Since OP only wants the innerText, you can make the foreach statement more concise by casting the XmlNodeList into a IEnumerable<XmlNode> and then projecting out the InnerText, i.e. dom.SelectNodes("//Segment[@Name = 'AAA']/node()").Cast<XmlNode>().Select(n => n.InnerText).ToList()
2

Try this:

System.Xml.Linq.XDocument doc = XDocument.Load(your file);

var nodes = 
     doc.Element("Loop").Element("Loop").Elements("Segment")
                .Where(input => (string)input.Attribute("Name") == "AAA")
                .Select(input => input.Elements()).ToList();

Then:

List<string> result = new List<string>();

foreach (List<XElement> item in nodes)
{
    result.AddRange(item.Select(i => i.Value));
}

4 Comments

Use (string)input.Attribute("Name") == "AAA" instead. Your code will throw an exception if there exists at least one Segment node without a "Name" attribute.
@HosseinNarimaniRad - thanks its working, but how can loop through all the nodes selected to get values of all those in a string?
@NareshKumar Edit your post and consider writing the string output you expect to reach.
@HosseinNarimaniRad - I have edited my post. Basically I wanted to know how do I iterate elements in nodes variable using foreach loop?
0

If you ever used linq-to-entities or linq-to-sql, there is a linq-to-xml you can use.

Comments

0

Do you can try this ?

XDocument xmlFile = XDocument.Load("myFile.xml");
foreach (var nodeSegment in xmlFile.Descendants("Loop"))
{
   foreach (var nodes in nodeSegment.Descendants().Where(e => e.Name.LocalName.StartsWith("Node")))
   {

   }
}

Comments

0

Try this out..

List<string> nodeDetails = new List<string>();

       var nodes = from n in XDocument.Load(@"D:\pfXml.xml")
                                              .Element("Loop")
                                              .Element("loop")
                                              .Elements("Segment")
                                      where (string)n.Attribute("Name") == "AAAA"
                                      select new
                                      {
                                          n1 = n.Element("Node1").Value,
                                          n2 = n.Element("Node2").Value,
                                          n3 = n.Element("Node3").Value,
                                          n4 = n.Element("Node4").Value
                                      };
        foreach (var node in nodes)
        {
            nodeDetails.Add(node.n1);
            nodeDetails.Add(node.n2);
            nodeDetails.Add(node.n3);
            nodeDetails.Add(node.n4);
        }

Comments

Your Answer

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