J.J.
J.J.

Reputation: 1118

Check if XML Document child node exists before parsing

I want to check if addresses child node delivery/invoice exist. Is there an easy way to accomplish this? Here is the code for parsing the xml nodes which are in a dictionary (importlist).

if (fileref.importList.ContainsKey("Addresses")) //here I want to check if addresses child node deliveryaddress/invoiceaddress exist
{
var deliveryAddress = order.Elements(ns + "Addresses")
.Elements(ns + "Delivery")
.Select(e => new Invoices.Address
{
Name = (string)e.Element(ns + "Name") == null ? null : (string)e.Element(ns + "Name"),
PostalCode = (string)e.Element(ns + "PostalCode") == null ? null : (string)e.Element(ns + "PostalCode"),
PostalArea = (string)e.Element(ns + "PostalArea") == null ? null : (string)e.Element(ns + "PostalArea"),
State = (string)e.Element(ns + "State") == null ? null : (string)e.Element(ns + "State"),
Street = (string)e.Element(ns + "Street") == null ? null : (string)e.Element(ns + "Street"),
Country = (string)e.Element(ns + "Country") == null ? null : (string)e.Element(ns + "Country"),
City = (string)e.Element(ns + "City") == null ? null : (string)e.Element(ns + "City"),

})
.Single();

var invoiceAddress = order.Elements(ns + "Addresses")
.Elements(ns + "Invoice")
.Select(e => new Invoices.Address
{

Name = (string)e.Element(ns + "Name") == null ? null : (string)e.Element(ns + "Name"),
PostalCode = (string)e.Element(ns + "PostalCode") == null ? null : (string)e.Element(ns + "PostalCode"),
PostalArea = (string)e.Element(ns + "PostalArea") == null ? null : (string)e.Element(ns + "PostalArea"),
State = (string)e.Element(ns + "State") == null ? null : (string)e.Element(ns + "State"),
Street = (string)e.Element(ns + "Street") == null ? null : (string)e.Element(ns + "Street"),
Country = (string)e.Element(ns + "Country") == null ? null : (string)e.Element(ns + "Country"),
City = (string)e.Element(ns + "City") == null ? null : (string)e.Element(ns + "City"),

})
.Single();

Invoices.Addresses addresses = new Invoices.Addresses();
addresses.Delivery = deliveryAddress;
addresses.Invoice = invoiceAddress;
} //end of addresses check

Here is the XML doc example:

<?xml version="1.0" encoding="utf-8"?>
<InvoiceOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <OrderId xmlns="http://24sevenOffice.com/webservices">115</OrderId>
  <CustomerId xmlns="http://24sevenOffice.com/webservices">21</CustomerId>
  <CustomerName xmlns="http://24sevenOffice.com/webservices">James Hertz</CustomerName>
  <Addresses xmlns="http://24sevenOffice.com/webservices">
    <Delivery>
      <Street>11 Shewell Walk</Street>
      <State>CT</State>
      <PostalCode>CO1 1WG</PostalCode>
      <PostalArea />
      <Name />
      <City>Test</City>
      <Country>US</Country>
    </Delivery>
    <Invoice>
      <Street>11 Shewell Walk</Street>
      <State>CT</State>
      <PostalCode>CO1 1WG</PostalCode>
      <PostalArea />
      <Name />
      <City>Test</City>
      <Country>US</Country>
    </Invoice>
  </Addresses>
  <OrderStatus xmlns="http://24sevenOffice.com/webservices">Offer</OrderStatus>
  <DateOrdered xmlns="http://24sevenOffice.com/webservices">2015-06-15T14:00:00Z</DateOrdered>
  <PaymentTime xmlns="http://24sevenOffice.com/webservices">14</PaymentTime>
  <IncludeVAT xsi:nil="true" xmlns="http://24sevenOffice.com/webservices" />
  <OrderTotalIncVat xmlns="http://24sevenOffice.com/webservices">0.0000</OrderTotalIncVat>
  <OrderTotalVat xmlns="http://24sevenOffice.com/webservices">0.0000</OrderTotalVat>
  <Currency xmlns="http://24sevenOffice.com/webservices">
    <Symbol>LOCAL</Symbol>
  </Currency>
  <TypeOfSaleId xmlns="http://24sevenOffice.com/webservices">-100</TypeOfSaleId>
  <InvoiceRows xmlns="http://24sevenOffice.com/webservices">
    <InvoiceRow />
  </InvoiceRows>
</InvoiceOrder>

Upvotes: 0

Views: 1025

Answers (1)

Charles Mager
Charles Mager

Reputation: 26213

In order to check, you'd need to do a similar query of your XML to see if the element you are looking for exists, for example:

var addressesExists = order.Elements(ns + "Addresses").Any()

But, as you'd then execute this query again straight afterwards, you could just change your Single to SingleOrDefault. This way, if it doesn't exist then the relevant address variable will be null (it will throw an exception if there is more than one address, though). In addition, as has been noted, your null checks are redundant and can be removed.

Tying this together, you delivery address query would be as follows:

var deliveryAddress = order.Elements(ns + "Addresses")
    .Elements(ns + "Delivery")
    .Select(e => new Invoices.Address
    {
        Name = (string)e.Element(ns + "Name"),
        PostalCode = (string)e.Element(ns + "PostalCode"),
        PostalArea = (string)e.Element(ns + "PostalArea"),
        State = (string)e.Element(ns + "State"),
        Street = (string)e.Element(ns + "Street"),
        Country = (string)e.Element(ns + "Country"),
        City = (string)e.Element(ns + "City"),

    }).SingleOrDefault();

This will be null if there is no address on this path.

Upvotes: 1

Related Questions