?
Solved

Find a node

Posted on 2009-04-21
15
Medium Priority
?
1,049 Views
Last Modified: 2013-11-11
I have a LINQ XElement like this. I want to find a node. I tried "nodes()" but i cant specify a node name:

 foreach (System.Xml.Linq.XElement xe in rule.CalculatorXml.Elements())
       {
          //if node is in ShippingMethod node...
                 
       }


-- I want to do replace this code with XElement
foreach (XmlNode methodNode in rule.SelectNodes("ShippingMethod"))
            {

             }
0
Comment
Question by:Camillia
  • 6
  • 5
  • 3
  • +1
15 Comments
 
LVL 39

Expert Comment

by:abel
ID: 24197654
Do you mean to find a specific node, or any node, or a text node, or an attribute node? Or, to make things easier, can you give an example of the input XML and point to the node you want to "capture"?
0
 
LVL 7

Author Comment

by:Camillia
ID: 24197730
I thought I posted a sample XML, sorry. It's below.

I need to find "ShippingMethod" and the attribute "Code". and "Destination"

Original code is like this:
 foreach (XmlNode methodNode in rule.Configuration.SelectNodes("ShippingMethod"))
            {
                if (methodNode.Attributes["Code"] != null)
                {  ...
                   foreach (XmlNode destinationNode in methodNode.SelectNodes("Destination"))
                        {
<ScoreRule>
  <ShippingMethod Code="UPS1DA">
    <Destination Country="US" Area="IL" Value="0" />
   </ShippingMethod>
</ScoreRule>

Open in new window

0
 
LVL 39

Expert Comment

by:abel
ID: 24198290
See the code below. The variable "shipping' contains all shipping methods, and the variable destination contains all Destination elements. In the last two simple loops I extract some information of these elements and put them to txtResult, giving me:

ShippingMethod/@Code="UPS1DA"Destination/@Country="US"
as output.


string xmlString = @"<ScoreRule>
                      <ShippingMethod Code='UPS1DA'>
                        <Destination Country='US' Area='IL' Value='0' />
                       </ShippingMethod>
                    </ScoreRule>";
TextReader textRdr = new StringReader(xmlString);
XDocument xdoc = XDocument.Load(textRdr);
 
var shippings = from elem in xdoc.Descendants("ShippingMethod") select elem;
var destinations = from elem in xdoc.Descendants("Destination") select elem;
 
foreach (XElement x in shippings)
    txtResults.Text += x.Name + "/@Code = " + x.Attribute("Code") + "\r\n";
 
foreach (XElement x in destinations)
    txtResults.Text += x.Name + "/@Country = " + x.Attribute("Country") + "\r\n";

Open in new window

0
Configuration Guide and Best Practices

Read the guide to learn how to orchestrate Data ONTAP, create application-consistent backups and enable fast recovery from NetApp storage snapshots. Version 9.5 also contains performance and scalability enhancements to meet the needs of the largest enterprise environments.

 
LVL 39

Assisted Solution

by:abel
abel earned 400 total points
ID: 24198296
clicked too soon, sorry, replace that with the following to match the results I mentioned

string xmlString = @"<ScoreRule>
                      <ShippingMethod Code='UPS1DA'>
                        <Destination Country='US' Area='IL' Value='0' />
                       </ShippingMethod>
                    </ScoreRule>";
TextReader textRdr = new StringReader(xmlString);
XDocument xdoc = XDocument.Load(textRdr);
 
var shippings = from elem in xdoc.Descendants("ShippingMethod") select elem;
var destinations = from elem in xdoc.Descendants("Destination") select elem;
 
foreach (XElement x in shippings)
    txtResults.Text += x.Name + "/@" + x.Attribute("Code") + "\r\n";
 
foreach (XElement x in destinations)
    txtResults.Text += x.Name + "/@" + x.Attribute("Country") + "\r\n";

Open in new window

0
 
LVL 7

Author Comment

by:Camillia
ID: 24198430
thanks , let me try.

Is there a way to cast XElement to XMLNode??
0
 
LVL 39

Expert Comment

by:abel
ID: 24198458
XmlNode is part of the DOM. XElement is part of LINQ. They cannot be cast to each other. It is usually best to either choose DOM or LINQ and not both (though you can mix and match).

To convert between the two you have to go all the way: serialize and load again.
0
 
LVL 9

Expert Comment

by:Sreedhar Vengala
ID: 24200118
To final result as Dictionary object as (Code, Destination, Country, Value)

Where your XML is :
<Rule>
      <ScoreRule>
        <ShippingMethod Code="UPS1DA">
            <Destination Country="US1" Area="IL1" Value="01" />
         </ShippingMethod>
      </ScoreRule>
      <ScoreRule>
        <ShippingMethod Code="UPS2DA">
            <Destination Country="US2" Area="IL2" Value="02" />
         </ShippingMethod>
      </ScoreRule>
      <ScoreRule>
        <ShippingMethod Code="UPS3DA">
            <Destination Country="US3" Area="IL3" Value="03" />
         </ShippingMethod>
      </ScoreRule>
      <ScoreRule>
        <ShippingMethod Code="UPS4DA">
            <Destination Country="US4" Area="IL4" Value="04" />
         </ShippingMethod>
      </ScoreRule>
</Rule>

May this will be helpful:


using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
 
namespace xml_Test
{
    class Program
    {
        private static Dictionary<string, string> Values    ;
 
        static void Main()
        {
      
            XDocument xdoc = XDocument.Load(@"C:\test.xml");
 
            List<XAttribute> attributes = (from c in xdoc.Descendants("ShippingMethod") select c.Attribute("Code")).ToList();
            var list = (from c in xdoc.Descendants("Destination")
                        select new
                                   { 
                                       Country = c.Attribute("Country"),
                                       Area = c.Attribute("Area"),
                                       Value = c.Attribute("Value")
                                   }).ToList();
 
 
            var finalresult = new List<Dictionary<string, string>>();
            for (int i = 0; i < attributes.Count; i++)
            {
                Values = new Dictionary<string, string>
                             {
                                 {"Shipping Method", attributes[i].Value},
                                 {"country", list[1].Country.Value},
                                 {"Area", list[1].Area.Value},
                                 {"Value", list[1].Value.Value}
                             };
                finalresult.Add(Values);
            }
        }
    }
}

Open in new window

0
 
LVL 9

Expert Comment

by:Sreedhar Vengala
ID: 24200172
Other way Try this :
 var results = (from item in xdoc.Descendants("ShippingMethod") 
                          select new
                                     {
                                         ShippingMethodCode = item.Attribute("Code").Value, 
                                         Country = item.Element("Destination").Attribute("Country").Value, 
                                         Area = item.Element("Destination").Attribute("Area").Value,
                                         Val = item.Element("Destination").Attribute("Value").Value,
                                     }).ToList();

Open in new window

0
 
LVL 7

Author Comment

by:Camillia
ID: 24200537
thanks sree_ven. will look at both solutions.
0
 
LVL 39

Expert Comment

by:abel
ID: 24200587
hey, don't forget mine, you have three now ;D
0
 
LVL 7

Author Comment

by:Camillia
ID: 24200812
yes, abel...do you ever sleep? :)
0
 
LVL 21

Accepted Solution

by:
naspinski earned 1200 total points
ID: 24201494
I think you guys are making this way too hard :)
string output = string.Empty;
XDocument x = XDocument.Load(filepath);
foreach (XElement xe in (from p in x.Descendants("ShippingMethod") where p.Attribute("Code") != null select p))
{
    foreach (XElement destinationNode in xe.Descendants("Destination"))
    {
        output += "ShippingMethod/@Code=" + xe.Attribute("Code") + "<br />";//using <br /> for break if this is web
        output += "Destination/@Countryr=" + destinationNode.Attribute("Country") + "<br />";
    }
}

Open in new window

0
 
LVL 9

Assisted Solution

by:Sreedhar Vengala
Sreedhar Vengala earned 400 total points
ID: 24201500
This Should do straight :


var results = (from item in xdoc.Descendants("ShippingMethod") 
                          select new
                                     {
                                         ShippingMethodCode = item.Attribute("Code").Value, 
                                         Country = item.Element("Destination").Attribute("Country").Value, 
                                         Area = item.Element("Destination").Attribute("Area").Value,
                                         Val = item.Element("Destination").Attribute("Value").Value,
                                     }).ToList();

Open in new window

0
 
LVL 39

Expert Comment

by:abel
ID: 24202616
> yes, abel...do you ever sleep? :)

haha, think we are in different timezones, but sleeping... I can do that at the end of my life more then enough :)

Funny, before posting my attempt at a solution, I tried the approach of naspinski, but didn't get it to work, because I was selecting the attributes list and trying to loop over them again (should also be possible). But this looks very nice, naspinski (though it depends whether you can consider it simpler).
0
 
LVL 7

Author Comment

by:Camillia
ID: 24203516
You guys are great. Thanks. Let me look at all this and try them.

>> but sleeping... I can do that at the end of my life more then enough :)
I have to quote you on this :)

Kamila.

0

Featured Post

Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It seems a simple enough task, yet I see repeated questions asking how to do it: how to pass data between two forms. In this article, I will show you the different mechanisms available for you to do just that. This article is directed towards the .N…
Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question