Jeff Brady
Jeff Brady

Reputation: 1498

How to I access deeper xdocument nodes?

I have the following XML file:

<Invoice_Ack>
    <Invoices>
        <Invoice>
            <Invoice_Number>123456</Invoice_Number>
            <Status>Rejected</Status>
            <Detail_Errors>
                <Detail_Error>
                    <ErrorID>0001</ErrorID>
                    <ErrorMessage>This is the error message</ErrorMessage>
                </Detail_Error>
                <Detail_Error>
                    <ErrorID>0502</ErrorID>
                    <ErrorMessage>This is another error message</ErrorMessage>
                </Detail_Error>
            </Detail_Errors>
        </Invoice>
    </Invoices>
</Invoice_Ack>

I can access the "Invoice_Number" and "Status" nodes with the following code, but I'm not sure how to also grab the "ErrorMessage" node. Here's what I have:

XDocument doc = XDocument.Load(file);

foreach(var invoice in doc.Descendants("Invoice"))
{
    string status = invoice.Element("Status").Value;
    string invoicenum = invoice.Element("Invoice_Number").Value;
}

But how do I get ErrorMessage? I tried

string error = invoice.Element("Detail_Errors").Element("Detail_Error").Element("ErrorMessage").Value;

But that gives me a "Object reference not set to an instance of an object" error.

How else can this be done? Thank you!!

Upvotes: 0

Views: 198

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500875

The code you've given works for the XML you've given. I suspect you've actually got an invoice which doesn't have any errors - and that's what's wrong.

You should loop over the errors:

foreach (var error in invoice.Elements("Detail_Errors").Elements("Detail_Error"))
{
    var id = error.Element("ErrorID").Value;
    var message = error.Element("ErrorMessage").Value;
    // Do whatever you want with the ID and message
}

Note the use of Elements("Detail_Errors") here - if there's always exactly one Detail_Errors element (possibly with no child elements), you could just use Element("Detail_Errors") but the code I've given will work even if there are no Detail_Errors elements.

Upvotes: 1

Related Questions