使用 C# 创建对象解析 XML
Using C# to create objects parsing XML
我花了 1.5 天时间尝试创建一个对象来解析 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 可以包含多个 RecipientStatus。 RecipientStatus 内部有一组 CustomFields。理想情况下,单个 CustomField 将上升到与类型、电子邮件、用户名等相同的级别。
Status、ID在EnvelopeStatus下,也包含了CustomFields的集合。此集合中真正需要的唯一节点是 'Value' 节点,因此理论上,Value 可以上升到与 Status 和 Id 相同的级别。
我尝试了很多不同的事情,现在回到原点。有没有办法解析这个 xml,以便设置这些 类 中的属性:
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; }
}
你可以这样做:
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()
};
使用 XPath 表达式的替代形式:
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()
};
尝试单个查询
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; }
}
}
我花了 1.5 天时间尝试创建一个对象来解析 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 可以包含多个 RecipientStatus。 RecipientStatus 内部有一组 CustomFields。理想情况下,单个 CustomField 将上升到与类型、电子邮件、用户名等相同的级别。
Status、ID在EnvelopeStatus下,也包含了CustomFields的集合。此集合中真正需要的唯一节点是 'Value' 节点,因此理论上,Value 可以上升到与 Status 和 Id 相同的级别。
我尝试了很多不同的事情,现在回到原点。有没有办法解析这个 xml,以便设置这些 类 中的属性:
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; }
}
你可以这样做:
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()
};
使用 XPath 表达式的替代形式:
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()
};
尝试单个查询
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; }
}
}