-3

I would like to fetch the string mentioned in 'Value' for various parameter available under 'Name' using c#. Here is my current xml as follows:

<DrWatson>
  <Sets>
    <Set>
      <APIParameters>
        <Parameter Name="SID_STAGE" Value="101198" Required="true" />
        <Parameter Name="SID_QE" Value="Test 91817" Required="true" />
      </APIParameters>
    </Set>
  </Sets>
</DrWatson>

I would like to fetch the '101198' available under 'Value' for Name = SID_STAGE. Please suggest how can i perform it.

user2778482
  • 59
  • 1
  • 8
  • 1
    parse xml with linq http://stackoverflow.com/questions/670563/linq-to-read-xml it's really hard to find – Kamil Budziewski Sep 17 '13 at 11:04
  • 1
    Please, next time provide some code you already have and describe problems you faced – Sergey Berezovskiy Sep 17 '13 at 11:22
  • It's a perfectly valid question. I don't think there's any need to provide any code, anyone relatively new to C# .NET wouldn't really know what classes to use. I don't see any good reason why the user should be downvoted, particularly considering that they are clearly a new user. It's extremely off-putting to be downvoted so harshly on a first set of questions. – Ciaran Gallagher Jan 06 '14 at 13:10

4 Answers4

3

You can parse parameters dictionary (that is natural way to store key-value pairs) with LINQ to XML:

var xdoc = XDocument.Load(path_to_xml);
var parameters = xdoc.Descendants("Parameter")
                     .ToDictionary(p => (string)p.Attribute("Name"),
                                   p => (string)p.Attribute("Value"));

var stage = parameters["SID_STAGE"];

Keep in mind, that you should check if parameter exists in dictionary before getting it (if it is possible that parameter can not be in your xml):

if (parameters.ContainsKey("SID_STAGE"))
    // get parameter value

Also with XPath you can make query more concrete (if it is possible that somewhere will be another Parameter elements):

var xpath = "DrWatson/Sets/Set/APIParameters/Parameter";
var parameters = xdoc.XPathSelectElements(xpath)
                     .ToDictionary(p => (string)p.Attribute("Name"),
                                   p => (string)p.Attribute("Value"));
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • nice approach with Dictionary, love it. Just afraid a bit of `ArgumentNullException` exception in cases when attribute Name is absent – Ilya Ivanov Sep 17 '13 at 11:15
  • @IlyaIvanov thanks, I assumed that parameter name is required (otherwise it makes no sense), but it simple solved with `Where(p => (string)p.Attribute("Name") != null)` filter :) – Sergey Berezovskiy Sep 17 '13 at 11:17
  • 1
    yes, sure. Just wanted to mention that. I had some negative experience, when I used `ToDictionary` on items, which key could be null. That wasn't quite obvious at that time) – Ilya Ivanov Sep 17 '13 at 11:18
3
var result = XElement.Parse(xmlString)
                     .Descendants("Parameter")
                     .First(node => (string)node.Attribute("Name") == "SID_STAGE")
                     .Attribute("Value");

Console.WriteLine(result.Value); //prints 101198

Will throw an exception of element with this attribute is absent. Consider using FirstOrDefault if you would like another behaviour.

Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • For this sample xml it will work, but what if there is another element with attribute `Name` equal to SID_STAGE? :) – Sergey Berezovskiy Sep 17 '13 at 11:19
  • 1
    @lazyberezovsky fixed by adding `Parameter` node name. Note that XML allows to have several `Parameter` nodes with equal `Name` attributes ;) This will cause troubles with both of our solutions, mine won't throw exception thou, which could be quite bad sometimes – Ilya Ivanov Sep 17 '13 at 11:22
  • Few more lines, and we will handle that :) `GroupBy(p => (string)p.Attribute("Name")).Where(g => g.Key != null).Select(g => g.First()).ToDictionary(...)` – Sergey Berezovskiy Sep 17 '13 at 11:26
0

Use a LINQ to XML query:

var xml = XDocument.Load("path...");
var foo = (from n in xml.Descendants("APIParameters")
           where n.Element("Parameter").Attribute("Name").Value == "SID_STAGE"
           select n.Element("Parameter").Attribute("Value").Value).FirstOrDefault();

Gives:

101198

DGibbs
  • 14,316
  • 7
  • 44
  • 83
  • I am getting an exception out there. – user2778482 Sep 17 '13 at 11:36
  • What exception is thrown and on what line? I've tested this and it works fine for me – DGibbs Sep 17 '13 at 11:39
  • Getting the following :Exception has been thrown by the target of an invocation. – user2778482 Sep 17 '13 at 11:42
  • I am getting this on Line 1 only – user2778482 Sep 17 '13 at 11:46
  • Which is this `var xml = XDocument.Load("path...");` - try not to just blindly copy and paste code. You need to set the filepath parameter of `XDocument.Load()`. The method takes a path to your XML or the XML string itself. Since I do not know the path to your XML, I have substituted this with `path...` purely as an example – DGibbs Sep 17 '13 at 11:47
  • var xml = XDocument.Load(FilePath_EXPRESS_API_SearchCriteria); i am using it this way only and i have verified and oberved that file path is valid – user2778482 Sep 17 '13 at 11:52
  • Doesn't look valid to me, the path should be enclosed in `""` for a start. Also, the path should lead to the file itself with the extension `.xml` which you don't have. – DGibbs Sep 17 '13 at 11:53
0
using System;
using System.Xml.Linq;
using System.Web;
namespace YourProjectName
{
    public static class XmlFileRetrieve
    {
        public static string GetParameterValue(string name)
        {
            try
            {
                string path = HttpContext.Current.Server.MapPath("~/YourFolderName/YourXmlFileName.xml");
                XDocument doc = XDocument.Load(path);
                if (!(doc == null))
                {
                    var parameter = (from el in doc.Root.Elements("Parameter")
                                where (string)el.Attribute("Name") == name
                                select (string)el.Attribute("value")).Select(keyvalue => new { name = keyvalue }).Single(); ;
                    return parameter.name;
                }
                return "";
            }
            catch (Exception e)
            {string error=e.Message;return "";
            }
        }
    }
}