Joe Ruder
Joe Ruder

Reputation: 2194

breaking out all of the elements in a XML file C#

From another question I had, a answer almost got me there but I have hit a snag. I need all of the deliveries from a descendant and they are all running together.

Current code I have tried (but it is only getting the first delivery section).

The problem that is being caused with the way I have tried below is that it does not handle the sections that have multiple sections.

I have a semi-working solution that uses data-tables but this is a much cleaner looking solution and I would really like to learn how to get it working like this.

var document = XDocument.Parse(xmlText);
            var doc = XDocument.Parse(xmlText);
            XNamespace ns0 = doc.Root.GetNamespaceOfPrefix("ns0");

            XElement sender = doc.Descendants(ns0 + "SenderNameAndAddress").FirstOrDefault();
            string[] senderAddress = sender.Descendants(ns0 + "Address").Elements().Select(x => (string)x).ToArray();

            XElement recipientDeliveries = doc.Descendants(ns0 + "RecipientDeliveries").FirstOrDefault();

            var results = recipientDeliveries.Elements(ns0 + "Recipient").Select(x => new
            {
                recipientCode = ((string)x.Descendants(ns0 + "RecipientCode").FirstOrDefault()),
                name = (string)x.Descendants(ns0 + "Name").FirstOrDefault(),
                address = x.Descendants(ns0 + "Address").Elements().Select(y => (string)y).ToArray(),
                deliveries = x.Descendants(ns0 + "Deliveries").Elements().Select(y => (string)y).ToArray(),
                deliveryID = (string)x.Descendants(ns0 + "DeliveryID").FirstOrDefault(),
                deliveryType = (string)x.Descendants(ns0 + "DeliveryType").FirstOrDefault(),
                deliveryRoute = (string)x.Descendants(ns0 + "DeliveryRoute").FirstOrDefault(),
                toteID = (string)x.Descendants(ns0 + "ToteID").FirstOrDefault(),
                nursingStation = (string)x.Descendants(ns0 + "NursingStation").FirstOrDefault()
            }).ToList();

This is the xml sample

<?xml version="1.0" encoding="UTF-8"?>
<ns0:AdvancedShippingNotices xmlns:ns0="http://www.omnicare.com/schema/AdvancedShippingNotices.xsd">
    <ns0:ASNID>4129114</ns0:ASNID>
    <ns0:CourierID>4SAMEDAY</ns0:CourierID>
    <ns0:SenderCode>598</ns0:SenderCode>
    <ns0:SenderNameAndAddress>
        <ns0:Name>Omnicare of San Diego</ns0:Name>
        <ns0:Address>
            <ns0:Line1>5601 Oberlin Drive, Suite 124</ns0:Line1>
            <ns0:CityTownOrLocality>San Diego</ns0:CityTownOrLocality>
            <ns0:StateOrProvince>CA</ns0:StateOrProvince>
            <ns0:PostalCode>92121-3709</ns0:PostalCode>
        </ns0:Address>
    </ns0:SenderNameAndAddress>
    <ns0:RecipientDeliveries>
        <ns0:Recipient>
            <ns0:RecipientCode>1019</ns0:RecipientCode>
            <ns0:RecipientNameAndAddress>
                <ns0:Name>VILLAGE SQUARE HEALTHCARE CTR</ns0:Name>
                <ns0:Address>
                    <ns0:Line1>1586 W SAN MARCOS BLVD</ns0:Line1>
                    <ns0:CityTownOrLocality>SAN MARCOS</ns0:CityTownOrLocality>
                    <ns0:StateOrProvince>CA</ns0:StateOrProvince>
                    <ns0:PostalCode>92069</ns0:PostalCode>
                </ns0:Address>
            </ns0:RecipientNameAndAddress>
            <ns0:Deliveries>
                <ns0:Delivery>
                    <ns0:DeliveryID>8930798-5</ns0:DeliveryID>
                    <ns0:DeliveryType>ROUTE</ns0:DeliveryType>
                    <ns0:DeliveryRoute>R0130</ns0:DeliveryRoute>
                    <ns0:ToteID>S5-278</ns0:ToteID>
                    <ns0:NursingStation>2</ns0:NursingStation>
                </ns0:Delivery>
                <ns0:Delivery>
                    <ns0:DeliveryID>8934056-1</ns0:DeliveryID>
                    <ns0:DeliveryType>ROUTE</ns0:DeliveryType>
                    <ns0:DeliveryRoute>IV</ns0:DeliveryRoute>
                    <ns0:ToteID>B-132</ns0:ToteID>
                    <ns0:NursingStation>1</ns0:NursingStation>
                </ns0:Delivery>
                <ns0:Delivery>
                    <ns0:DeliveryID>8933908-1</ns0:DeliveryID>
                    <ns0:DeliveryType>CYCLE</ns0:DeliveryType>
                    <ns0:DeliveryRoute>CYCLE</ns0:DeliveryRoute>
                    <ns0:ToteID>B-132</ns0:ToteID>
                    <ns0:NursingStation>1</ns0:NursingStation>
                </ns0:Delivery>
            </ns0:Deliveries>
        </ns0:Recipient>
        <ns0:Recipient>
            <ns0:RecipientCode>20366</ns0:RecipientCode>
            <ns0:RecipientNameAndAddress>
                <ns0:Name>OAKMONT OF ESCONDIDO HILLS</ns0:Name>
                <ns0:Address>
                    <ns0:Line1>3012 BEAR VALLEY PKWY</ns0:Line1>
                    <ns0:CityTownOrLocality>ESCONDIDO</ns0:CityTownOrLocality>
                    <ns0:StateOrProvince>CA</ns0:StateOrProvince>
                    <ns0:PostalCode>92025</ns0:PostalCode>
                </ns0:Address>
            </ns0:RecipientNameAndAddress>
            <ns0:Deliveries>
                <ns0:Delivery>
                    <ns0:DeliveryID>8930798-4</ns0:DeliveryID>
                    <ns0:DeliveryType>ROUTE</ns0:DeliveryType>
                    <ns0:DeliveryRoute>R0130</ns0:DeliveryRoute>
                    <ns0:ToteID>F1-101</ns0:ToteID>
                    <ns0:NursingStation>AL</ns0:NursingStation>
                </ns0:Delivery>
            </ns0:Deliveries>
        </ns0:Recipient>
    </ns0:RecipientDeliveries>
</ns0:AdvancedShippingNotices>

Upvotes: 1

Views: 146

Answers (2)

iSR5
iSR5

Reputation: 3498

Not sure if you actually use class models or not. But I did a little adjustment for for what's worth (It's will give you more flexibility with the data).

classes :

public class Recipient

    {
        public int RecipientCode { get; set; }
        public RecipientInfo RecipientNameAndAddress { get; set; }
        public IList<RecipientDelivery> Deliveries { get; set; }
    }

    public class RecipientInfo
    {
        public string Name { get; set; }
        public RecipientAddress Address { get; set; }

    }
    public class RecipientAddress
    {
        public string Line1 { get; set; }

        public string CityTownOrLocality { get; set; }

        public string StateOrProvince { get; set; }

        public string PostalCode { get; set; }
    }
    public class RecipientDelivery
    {
        public string DeliveryID { get; set; }

        public string DeliveryType { get; set; }

        public string DeliveryRoute { get; set; }

        public string ToteID { get; set; }
        public string NursingStation { get; set; }

    }

then the work :

    var doc = XDocument.Parse(file);

    XNamespace ns0 = doc.Root.GetNamespaceOfPrefix("ns0");

    XElement recipientDeliveries = doc.Descendants(ns0 + "RecipientDeliveries").FirstOrDefault();

    var recipients = recipientDeliveries.Descendants(ns0 + "Recipient").ToList();

    var RecipientList = new List<Recipient>();


    foreach (var item in recipients)
    {
        var deliveries = item.Descendants(ns0 + "Deliveries").FirstOrDefault();

        var deliveriesNodes = deliveries.Descendants(ns0 + "Delivery").ToList();

        var recipientInfo = item.Descendants(ns0 + "RecipientNameAndAddress").FirstOrDefault();

        var recipientAddress = recipientInfo.Descendants(ns0 + "Address").FirstOrDefault();

        var deliverList = new List<RecipientDelivery>();


        foreach (var del in deliveriesNodes)
        {
            var delivery = new RecipientDelivery()
            {
                DeliveryID = del.Element(ns0 + "DeliveryID").Value,
                DeliveryType = del.Element(ns0 + "DeliveryType").Value,
                DeliveryRoute = del.Element(ns0 + "DeliveryRoute").Value,
                ToteID = del.Element(ns0 + "ToteID").Value,
                NursingStation = del.Element(ns0 + "NursingStation").Value
            };

            deliverList.Add(delivery);
        }

        var recipient = new Recipient()
        {
            RecipientCode = Convert.ToInt32(item.Element(ns0 + "RecipientCode").Value),

            RecipientNameAndAddress = new RecipientInfo()
            {
                Name = recipientInfo.Element(ns0 + "Name").Value.ToString(),

                Address = new RecipientAddress()
                {
                    Line1 = recipientAddress.Element(ns0 + "Line1").Value.ToString(),
                    CityTownOrLocality = recipientAddress.Element(ns0 + "CityTownOrLocality").Value.ToString(),
                    StateOrProvince = recipientAddress.Element(ns0 + "StateOrProvince").Value.ToString(),
                    PostalCode = recipientAddress.Element(ns0 + "PostalCode").Value.ToString()
                },

            }, 

            Deliveries = deliverList
        };

        RecipientList.Add(recipient);
    }

Then the whole Recipients will be in RecipientList, which you can use.

Upvotes: 2

jdweng
jdweng

Reputation: 34431

A small modification from previous results :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XNamespace ns0 = doc.Root.GetNamespaceOfPrefix("ns0");

            XElement sender = doc.Descendants(ns0 + "SenderNameAndAddress").FirstOrDefault();
            string[] senderAddress = sender.Descendants(ns0 + "Address").Elements().Select(x => (string)x).ToArray();

            XElement recipientDeliveries = doc.Descendants(ns0 + "RecipientDeliveries").FirstOrDefault();

            var results = recipientDeliveries.Elements(ns0 + "Recipient").Select(x => new
            {
                name = (string)x.Descendants(ns0 + "Name").FirstOrDefault(),
                address = x.Descendants(ns0 + "Address").Elements().Select(y => (string)y).ToArray(),
                deliveries = x.Descendants(ns0 + "Delivery").Select(y => new {
                    deliveryID = (string)y.Descendants(ns0 + "DeliveryID").FirstOrDefault(),
                    deliveryType = (string)y.Descendants(ns0 + "DeliveryType").FirstOrDefault(),
                    deliveryRoute = (string)y.Descendants(ns0 + "DeliveryRoute").FirstOrDefault(),
                    toteID = (string)y.Descendants(ns0 + "ToteID").FirstOrDefault(),
                    nursingStation = (string)y.Descendants(ns0 + "NursingStation").FirstOrDefault()
                }).ToList()
            }).ToList();
        }
    }
}

Upvotes: 1

Related Questions