0

Given the following XML file:

<root>
   <country>
       <name></name>
       <locationOU>null</location>
   </country>
   <country>
       <name>Sweden</name>
       <locationOU>Some Value</locationOU>
   </country>
   <country>
       <name>Lithuania</name>
       <locationOU>Some Value</locationOU>
   </country>
   <country>
       <name>Belgium</name>
       <locationOU>Some Value</locationOU>
   </country>
</root>

How do I get the value of locationOU based on name value eg. name = Sweden?

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
wads
  • 123
  • 11
  • It seems you would need to parse the file into objects. (Similar to deserializing a json). Would this post solve your issue?: https://stackoverflow.com/questions/3187444/convert-xml-string-to-object – Francois Louw Sep 30 '22 at 07:14

4 Answers4

3

You can work with XPath via XPathSelectElement(XNode, String).

using System.Xml.Linq;
using System.Xml.XPath;

// Read XML file
XDocument root = XDocument.Load(/* Your XML file path */);

// Read XML from string
// XDocument root = XDocument.Parse(xml);

XElement result = root.XPathSelectElement("/root/country[name='Sweden']");
        
string locationOU = result.Element("locationOU").Value;

Demo @ .NET Fiddle

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
  • Thanks for your answer! It seems like a get an error on the `XDocument root = XDocument.Parse("Locations.xml");` that says: "Data at the root level is invalid. Line 1, position 1" – wads Sep 30 '22 at 11:15
  • No, you use `XDocument.Parse()` by providing the XML string. If you want read XML from file. use [`XDocument.Load("Your file path")`](https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xdocument.load?view=net-6.0). – Yong Shun Sep 30 '22 at 13:16
  • Ah! That removed the error, thank you :) However `locationOU` is null. I can see when I debug, that it has the correct country and that the value for is there – wads Sep 30 '22 at 13:25
  • Never mind! I see that I had a typo in my XML :) Thanks for the help! – wads Sep 30 '22 at 13:29
1

I like using xml linq with a dictionary :

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication40
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, string> dict = doc.Descendants("country")
                .GroupBy(x => (string)x.Element("name"), y => (string)y.Element("locationOU"))
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            string sweedenLocation = dict["Sweden"];
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • I notice that the `Value` are all null. If I look at Sweden for instance, the `key` is Sweden and the `Value` is null – wads Sep 30 '22 at 11:45
0
XDocument doc = XDocument.Parse(XML_TEXT);
XElement rootElement = doc.XPathSelectElement("root");
var countries = rootElement?.Descendants().Where(e => e.Name.LocalName.Equals("country"));
var yourCountry = countries.Descendants().FirstOrDefault(d => d.Name.LocalName.Equals("locationOU") && d.Value == "Sweden");
vhr
  • 1,528
  • 1
  • 13
  • 21
  • I get an error on `e =>`: "A local or parameter named 'e' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter" – wads Sep 30 '22 at 12:54
0

You can use XPath with above answers @Yong Shun

Or You can use DataSet as bellow:

DataSet ds=new DataSet();
ds.readXml(filename);
DataTable dt=ds.Tables[0];
string name="Sweden";
foreach(DataRow dr in dt.Select(String.Format("name='{0}'",name))
{
    string locationOU=dr["locationOU"].toString();
}
D T
  • 3,522
  • 7
  • 45
  • 89