6

I've looked at a lot of resources, done a lot of research, and tried many "best-guesses" to access a single element at a time using WebMatrix with C#, web-pages, however nothing I am trying is getting through.

Consider a simple xml document that looks like this:

<root>
    <requisitionData>
        <element1>I am element 1</element1>
        <element2>I am element 2</element2>
    </requisitionData>
</root>

I know I can use a foreach loop, like so:

@using System.Xml.Linq

XDocument doc = XDocument.Load(Server.MapPath("~/User_Saves/cradebaugh/testFile.xml"));

foreach (XElement element in doc.Descendants("requisitionData"))
{
    @element.Value
}

And that, of course, works fine. But what if I simply wanted to store the single element, <element1>'s value in a string variable?

I've looked here (link below), but I can't make heads or tails of this code (it barely even looks like C# to me, but then again, I'm so new to parsing XML...):

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/b14ce4d1-77f1-420d-ad91-0989794a1d45/

I've also checked here: How to Get XML Node from XDocument

But the code shown makes no sense to me here either. I keep thinking there must be a simpler way to do this, hopefully without learning a whole new querying approach.

---------------------------------THINGS I'VE TRIED---------------------------------

XDocument doc = XDocument.Load(Server.MapPath("~/User_Saves/cradebaugh/testFile.xml"));

string element = doc.Descendants("requisitionData").Descendants("element1").Value;

Error I receive: "missing using directive or assembly reference

XDocument doc = XDocument.Load(Server.MapPath("~/User_Saves/cradebaugh/testFile.xml"));

XElement element = doc.Descendants("element1");
string val = element.Value;

Error I receive: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Xml.Linq.XElement'. An explicit conversion exists (are you missing a cast?)

I have, indeed, tried other things, but I get pretty much the same errors as shown above. Am I making this harder than it is, or am I oversimplifying it?

-------------------------UPDATE------------------------------

I was able to get this to work:

string element = doc.Element("root").Element("requisitionData").Element("element1").Value;

@element

However, one thing that concerns me about this approach is that .Element selects the 'first' match, so in an xml document that looks like this:

<root>
    <requisitionData>
        <element1>I am element 1</element1>
        <element2>I am element 2</element2>
    </requisitionData>
    <requisitionData>
        <element1>I am element 1</element1>
        <element2>I am element 2</element2>
    </requisitionData>
</root>

How could I access the second occurrence of <element1>?

Community
  • 1
  • 1
VoidKing
  • 6,282
  • 9
  • 49
  • 81
  • After having this issue resolved for a couple of days (thanks to the answer below), I'm gonna have to say that using XPathSelectElement(s) seems to be the way to go. XPath is powerful (way more than I realized) accurate, and completely flexible, whether I want a single element or many. – VoidKing Apr 12 '13 at 13:25

1 Answers1

5
@using System.Xml.Linq

XDocument doc = XDocument.Load(Server.MapPath("~/User_Saves/cradebaugh/testFile.xml"));

foreach (XElement element in doc.Element("root").Element("requisitionData").Descendants())
{
    string value = element.Value;
}

or with XPath:

@using System.Xml.Linq
@using System.Xml.XPath

XDocument doc = XDocument.Load(Server.MapPath("~/User_Saves/cradebaugh/testFile.xml"));

foreach (XElement element in doc.XPathSelectElement("//requisitionData").Descendants())
{
    string value = element.Value;
}

UPDATE:

And if you wanted to select for example the second <element1> node from your updated example:

string value = doc.XPathSelectElement("//requisitionData[2]/element1").Value;
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks for the answer but I am explicitly wanting only a single element, thus alleviating the need for a code 'loop' – VoidKing Apr 09 '13 at 14:01
  • Also, I don't see how this selects a single element. There is more than one result that will be iterated through, given the foreach loop conditions. – VoidKing Apr 09 '13 at 14:21
  • Which particular node in the XML do you want? You could use the XPath example I have shown in my answer to get any specific node you like. For example if you wanted to get the value of the first `` node you would have written `string value = doc.XPathSelectElements("//requisitionData/element1").First().Value;`. – Darin Dimitrov Apr 09 '13 at 21:01
  • I certainly have no problem studying XPath, but let me express my thoughts this way: If I wanted to do this "client-side" (which I really don't) I could simply use a jQuery(CSS) selector to grab any single element by id, or grab multiples by class (or tag name for that matter) and iterate through them using .length. I feel like I have full control over exactly which elements I want to select and gather the data from. I would love to achieve this level of control "server-side" if possible (I'm sure it is, at least with XPath, although it may not be as simple). – VoidKing Apr 10 '13 at 13:08
  • Until your examples, though, I had no idea how to use XPath with C#.net, so, again, thank you for that! – VoidKing Apr 10 '13 at 13:10
  • I really don't understand what you are trying to achieve and what problems are you encountering. The `doc.XPathSelectElements("//requisitionData/element1")` expression will give you a list of all `` nodes. Isn't what you were asking for? Also I don't see what client side CSS has to do with the question here. All the examples are using server side code. – Darin Dimitrov Apr 10 '13 at 13:14
  • I'm sorry if I have confused you, but the question is pretty clear, what I am really asking is how to select a "single" element (not a list, not a collection, not all ``s but a single individual `` You're right "client-side" has nothing to do with this, except that I was simply using it as an example to explain the level of control I would like to achieve "server-side". Is there a way to use XPath (or any other C#.net method) to select a single element by 'id' or 'class', by any chance? Again, sorry for the confusion, but the original question states "single element" – VoidKing Apr 10 '13 at 13:29
  • Like this: `doc.XPathSelectElement("//requisitionData/element1")`. And if you wanted the second `element1` then simply adapt your XPath expression: `doc.XPathSelectElement("//requisitionData[2]/element1")`. I have updated my answer to provide you with a specific example. – Darin Dimitrov Apr 10 '13 at 13:36