1
<row>
    <id>9578</id>
    <processes>
        <process ID="PROCESS A">
            <subprocess ID ="STEP A">
                <val>abcde</val>
            </subprocess>
        </process>
        <process ID="PROCESS B">
            <subprocess ID ="STEP B">
                <val>fghij</val>
            </subprocess>
        </process>
        <process ID="PROCESS C">
            <subprocess ID ="STEP C">
                <val>klmno</val>
            </subprocess>
        </process>
    </processes>
<row>

I am trying to get the data in the val element, but am having trouble. So far, this is what I have:

XmlNodeReader nodereader = new XmlNodeReader(Xdoc);
nodereader.MoveToContent();
var xdoc = XDocument.Load(nodereader); 
var doc_list = xdoc.Descendants("row").Select(x => new
{
    id = x.Element("id").Value,
    ProcessA = x.Element("processes").Elements("process").Single(attr => attr.Attribute("ID").Value == "PROCESS A").Value 
}).ToList();

ProcessA will contain the values of the val element (in this case, abcde). But I keep getting a NullReferenceException. I think I'm almost on the right track, but I still need a little help.

EDIT Thank you everyone for your help but I realize my code works. The issue was just a spelling error due to the id. Instead of

id = x.Element("id").Value,

I accidentally did

id = x.Element("Id").Value,

which resulted in the NullReferenceException for the LINQ. My code to get the val element worked. Moral of the story: sometimes the error might not be where you think it is.

5
  • Hello, and welcome to Stack Overflow. What object reference are you getting the NullReferenceException on? Also, what does Element("id") represent? Commented Mar 5, 2020 at 8:37
  • Aside, another approach might be to use an xpath query. Commented Mar 5, 2020 at 8:42
  • Can you provide a minimal reproducible example? As you can see from this fiddle, your code works fine with the example XML. I can only assume your real XML has some of the expected elements or attributes missing for some of the row elements. Commented Mar 5, 2020 at 14:54
  • I tried the xpath query but it didn't work because the xpath is more complicated than the above example. Thank you for you sugesstion! Commented Mar 6, 2020 at 7:05
  • Thank you for making me double check my code Charles! I checked my code again after your comment and turns out that I had a spelling error on the "id" tag part. Commented Mar 6, 2020 at 7:07

1 Answer 1

4

Is this what you want to do?

var doc = XDocument.Parse(@"<row>
        <id>9578</id>
        <processes>
            <process ID=""PROCESS A"">
                <subprocess ID =""STEP A"">
                    <val>abcde</val>
                </subprocess>
            </process>
            <process ID=""PROCESS B"">
                <subprocess ID =""STEP B"">
                    <val>fghij</val>
                </subprocess>
            </process>
            <process ID=""PROCESS C"">
                <subprocess ID =""STEP C"">
                    <val>klmno</val>
                </subprocess>
            </process>
        </processes>
    </row>");

var doc_list = doc
.Elements("row")
.Elements("processes")
.Elements("process")
.Elements("subprocess")
.Select(x => new{
        Id = x.Attribute("ID").Value,
        ProcessVal = x.Element("val").Value
    })

Alternative using XPath instead:

var doc_list = doc
.XPathSelectElements(@"/row/processes/process/subprocess")
.Select(x => new{
    Id = x.Attribute("ID").Value,
    ProcessVal = x.Element("val").Value
})
Sign up to request clarification or add additional context in comments.

Comments

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.