【问题标题】:Using C# to create objects parsing XML使用 C# 创建解析 XML 的对象
【发布时间】:2017-03-26 04:33:22
【问题描述】:

我花了 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 会提升到与 Type、Email、UserName 等相同的级别。

状态、ID 位于 EnvelopeStatus 下,其中还包含一组自定义字段。此集合中唯一真正需要的节点是“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; }
}

【问题讨论】:

    标签: c# xml linq-to-xml xelement


    【解决方案1】:

    你可以这样做:

    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()
    };
    

    【讨论】:

      【解决方案2】:

      尝试单个查询

      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; }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 1970-01-01
        • 2012-07-06
        • 1970-01-01
        • 1970-01-01
        • 2012-05-17
        • 2014-06-15
        相关资源
        最近更新 更多