0

I've spent 1.5 days trying to create an object parsing XML:

<EnvelopeStatus>
 <RecipientStatuses>
  <RecipientStatus>
   <Type>Signer</Type>
            <Email>johndoe@gmail.com</Email>
            <UserName>Doe, John</UserName>            
            <Status>Completed</Status>            
            <CustomFields>
               <CustomField>1001</CustomField>
            </CustomFields>
  </RecipientStatus>
  <RecipientStatus>
   <Type>Signer</Type>
            <Email>maryjane@gmail.com</Email>
            <UserName>Jane, Mary</UserName>            
            <Status>Sent</Status>            
            <CustomFields>
               <CustomField>1002</CustomField>
            </CustomFields>
  </RecipientStatus>
 </RecipientStatuses>
 <Status>Completed</Status>
 <Id>25b9b7e8-c4c0-4711-a80c-24663f0dc6ed</Id>
 <CustomFields>
  <CustomField>
   <Name>Url</Name>            
            <Required>False</Required>
            <Value>http://google.com</Value>
         </CustomField>
         <CustomField>
            <Name>List</Name>            
            <Required>False</Required>
            <Value>Blue</Value>
         </CustomField>
         <CustomField>
            <Name>ItemId</Name>            
            <Required>False</Required>
            <Value>2</Value>
         </CustomField>
</EnvelopeStatus>

RecipientStatuses can contain many RecipientStatus. Inside of RecipientStatus there is a collection of CustomFields. Ideally, the single CustomField would move up to same level as Type, Email, UserName, etc.

Status, ID are under EnvelopeStatus, which also contain a collection of CustomFields. The only node really needed in this collection is 'Value' node, so theoretically, Value could move up to same level as Status and Id.

I have tried many different things and am back to square one. Is there a way to parse this xml, so that properties in these classes are set:

public class Request
{
    public string Id { get; set; }
    public string Status { get; set; }
    public string Url { get; set; }
    public string List { get; set; }
    public string ItemId { get; set; }
    public List<Signer> Signers { get; set; }
}
public class Signer
{
    public string Type { get; set; }    
    public string Email { get; set; }
    public string UserName { get; set; }
 public int UserId { get; set; }
}
obautista
  • 3,517
  • 13
  • 48
  • 83

2 Answers2

0

You can do this way :

var doc = XElement.Load("path to your XML file");
var req = new Request
{
    Id = (string)doc.Element("Id"),
    Status = (string)doc.Element("Status"),
    Url = (string)doc.Element("CustomFields")
                     .Elements("CustomFields")
                     .Where(cf => (string)cf.Element("Name") == "Url")
                     .Select(cf => (string)cf.Element("Value"))
                     .First(),
    //Follow `Url` example above to populate `List` and `ItemId` properties
    Signers = doc.Elements("RecipientStatuses")
                 .Elements("RecipientStatus")
                 .Select(o => new Signer
                 {
                     Type = (string)o.Element("Type"),
                     //Follow `Type` example above to populate `Email` and `UserName` properties
                     UserId = (int)o.Element("CustomFields").Element("CustomField")
                 })
                 .ToList()
};

Alternative form using XPath expressions :

var doc = XElement.Load("path to your XML file");
var req = new Request
{
    Id = (string)doc.XPathSelectElement("Id"),
    Status = (string)doc.XPathSelectElement("Status"),
    Url = (string)doc.XPathSelectElement("CustomFields/CustomFields[Name='Url']/Value"),
    //Follow `Url` example above to populate `List` and `ItemId` properties
    Signers = doc.XPathSelectElements("RecipientStatuses/RecipientStatus")
                 .Select(o => new Signer
                 {
                     Type = (string)o.Element("Type"),
                     //Follow `Type` example above to populate `Email` and `UserName` properties
                     UserId = (int)o.XPathSelectElement("CustomFields/CustomField")
                 })
                 .ToList()
};
har07
  • 88,338
  • 12
  • 84
  • 137
0

Try a single query

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);
            Request request = doc.Elements("EnvelopeStatus").Select(x => new  Request() {
                Id = (string)x.Element("Id"),
                Status = (string)x.Element("Status"),
                Url = (string)x.Descendants("CustomField").Where(y => (string)y.Descendants("Name").FirstOrDefault() == "Url").Select(z => z.Element("Value")).FirstOrDefault(),
                ItemId = (int)x.Descendants("CustomField").Where(y => (string)y.Descendants("Name").FirstOrDefault() == "ItemId").Select(z => z.Element("Value")).FirstOrDefault(),
                List = (string)x.Descendants("CustomField").Where(y => (string)y.Descendants("Name").FirstOrDefault() == "List").Select(z => z.Element("Value")).FirstOrDefault(),
                Signers = x.Descendants("RecipientStatus").Select(y => new Signer() {
                    Type = (string)y.Descendants("Type").FirstOrDefault(),
                    Email = (string)y.Descendants("Email").FirstOrDefault(),
                    UserName = (string)y.Descendants("UserName").FirstOrDefault(),
                    UserId = (int)y.Descendants("CustomField").FirstOrDefault()
                }).ToList()
            }).FirstOrDefault();
        }
    }
    public class Request
    {
        public string Id { get; set; }
        public string Status { get; set; }
        public string Url { get; set; }
        public string List { get; set; }
        public int ItemId { get; set; }
        public List<Signer> Signers { get; set; }
    }
    public class Signer
    {
        public string Type { get; set; }
        public string Email { get; set; }
        public string UserName { get; set; }
        public int UserId { get; set; }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20