LINQ / XML - 存储在自定义类中具有不同名称的子节点

时间:2015-07-02 19:10:38

标签: c# xml linq

数据示例:

<property>
  <price>2080000</price>
  <country>France</country>
  <currency>euro</currency>
  <locations>
    <location_9>Ski</location_9>
    <location_16>50km or less to airport</location_16>
    <location_17>0-2KM to amenities</location_17>
  </locations>
  <secondaryproptypes>
    <secondaryproptypes_1>Holiday Home</secondaryproptypes_1>
  </secondaryproptypes>
  <features>
    <features_30>Woodburner(s)</features_30>
    <features_9>Private parking</features_9>
    <features_23>Mountain view</features_23>
    <features_2>Mains Drains</features_2>
</features>

属性类的示例:

public class Property
    {
        public decimal price { get; set; }
        public string country { get; set; }
        public string currency { get; set; }

        public List<Location> locations { get; set; }
    }

地点类示例:

public class Location
    {
        public string location { get; set; }
    }

主要代码:(也试过很多衍生品,但这就是我放弃时的表现)

public void LoadXMLURL()
    {
        XDocument document = XDocument.Load("file.xml"); 

        var properties = (from p in document.Root.Elements("property")
                          select new Property
                          {

                              price = Convert.ToDecimal(p.Element("price").Value),
                              country = p.Element("country").Value,
                              currency = p.Element("currency").Value,
                              locations = new List<Location>(from l in p.Descendants("location")
                                                             select new Location
                                                             {
                                                                 location = (string)l
                                                             })
                          }

                              ).ToList();

我尝试了多种存储位置数据节点列表的方法。如数组和其他列表。

现在我认为我的主要问题是因为节点是变化的; &#34; location_9&#34; &#34; location_16&#34;

我无法像以前的节点一样严格指定要查看的节点。

2 个答案:

答案 0 :(得分:0)

好消息是,您抓取的节点在<locations>元素中组合在一起,因此您可以使用p.Element("locations").Elements()而不是p.Desendants("location")

这里有一些在LINQPad中运行的代码:

void Main()
{
    var str = @"
    <root>
    <property>
    <price>2080000</price>
    <country>France</country>
    <currency>euro</currency>
    <locations>
        <location_9>Ski</location_9>
        <location_16>50km or less to airport</location_16>
        <location_17>0-2KM to amenities</location_17>
    </locations>
    <secondaryproptypes>
        <secondaryproptypes_1>Holiday Home</secondaryproptypes_1>
    </secondaryproptypes>
    <features>
        <features_30>Woodburner(s)</features_30>
        <features_9>Private parking</features_9>
        <features_23>Mountain view</features_23>
        <features_2>Mains Drains</features_2>
    </features></property>
    </root>";
    var document = XDocument.Parse(str);
    var properties = 
        (from p in document.Root.Elements("property")
                    select new Property
                    {

                        price = Convert.ToDecimal(p.Element("price").Value),
                        country = p.Element("country").Value,
                        currency = p.Element("currency").Value,
                        locations = new List<Location>(from l in p.Element("locations").Elements()
                                                    select new Location
                                                    {
                                                        location = (string)l
                                                    })
                    }

                        ).ToList()
                        .Dump();
}

public class Property
{
    public decimal price { get; set; }
    public string country { get; set; }
    public string currency { get; set; }

public List<Location> locations { get; set; }
}

public class Location
{
    public string location { get; set; }
}

答案 1 :(得分:0)

一旦有父母,只需通过Elements一般性地要求孩子。这是一个例子

locations = p.Descendants("locations")
             .Elements()
             .Select (elm => new Location()
                               {
                                  location = elm.Value
                               } );