1

I am trying to read the following XML file:

<?xml version="1.0" encoding="utf-8"?>
<Connection name="default">
  <Attribute name="server" value="localhost" />
  <Attribute name="database" value="mp" />
  <Attribute name="uid" value="root" />
  <Attribute name="password" value="m123" />
  <Attribute name="code" value="MK" />
</Connection>

With the following code:

        var doc = XDocument.Load("DBConnect.xml");
        var values = doc.XPathSelectElements("//Connection[@name='default']");
        foreach (var item in values)
        {
            foreach (var att in item.Elements("Attribute"))
            {
                _server = att.Attribute("server").Value;
                _database = att.Attribute("database").Value;
                _uid = att.Attribute("uid").Value;
                _password = att.Attribute("password").Value;
                _code = att.Attribute("code").Value;
            }
        }

However, I don't seem to be getting the correct output. I am getting an error message which tells me _server is null. Any idea why? I don't think I am correctly referencing the XML attribute values I want to get a hold of.

5
  • 1
    Because your XPath uses Mapping and the element's name is Connection? When you say you don't seem to be getting the correct output, what output are you getting? Commented Jan 24, 2015 at 20:17
  • @JLRishe - thanks, but its not telling me that _server is null. I commented it out and checked through each of the variables in the foreach loop that I am assigning the XML value to, and they are all coming up as null Commented Jan 24, 2015 at 20:19
  • Could you be more specific about the "output" you get. Commented Jan 24, 2015 at 20:20
  • "server" is the value of the attribute, not the attribute name Commented Jan 24, 2015 at 20:21
  • @steve16351 - thanks for clearing that up, how would I get the value of the server attribute name? Commented Jan 24, 2015 at 20:23

3 Answers 3

4

One clean approach that you can use:

var values = doc.XPathSelectElements("//Connection[@name='default']")
                .Single()
                .Elements("Attribute")
                .ToDictionary(el => (string)el.Attribute("name"),
                              el => (string)el.Attribute("value"));

_server = values["server"];
_database = values["database"];
_uid = values["uid"];
_password = values["password"];
_code = values["code"];

values is an IDictionary<string, string>, so you can use it to retrieve any additional attributes that are added, without modifying the original LINQ code.

Sign up to request clarification or add additional context in comments.

1 Comment

Actually like this answer more than the accepted answer. Both will work, but this one is cleaner.
2

The issue is that you are looping through elements called Attribute and trying to find XML attributes there. Your logic would indicate that there should be all 5 XML attributes on each XML element called Attribute. Try using such code instead:

var values = doc.XPathSelectElements("//Connection[@name='default']");
_server = values.Elements("Attribute")   //look for an element called Attribute
             .Where(el => el.Attribute("name").Value == "server")  //which has attribute name="server"
             .Single()    //there should be only single element
             .Attribute("value").Value; //get the value of attribute value
// Repeat that for all other attributes (_database, _uid, etc.)

3 Comments

I like this approach better
I keep getting Replace with single call to Single(..) at values.Elements("Attribute").Where(el => el.Attribute("name").Value == "server").Single() - what does it mean?
It means that instead of Where(...).Single() you could use Single(el => el.Attribute("name").Value == "server") which gives an identical functionality
1

There is no attributes named "server", "database", "uid", "password" or "code". They're all values of the attributes named "name" which means you call Attribute("name") and not the value of it. Ex.

var attrVal = attr.Attribute("name").Value;
if (attrVal == "server")
    _server = attrVal.Value;
// ... etc

In case the above doesn't work try this.

var attrVal = attr.Attribute("name").Value;
if (attrVal == "server")
    _server = attr.Attribute("value").Value;
// ... etc

1 Comment

@methuselah You shouldn't edit other people's answers to comment on their answer or add your own code. If you want to show us the code that you ultimately used, you can add it in an answer of your own.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.