2011-12-07 132 views
8

解析XML對象

<Model> 
    <Components> 
     <Component name="a" id="aaa" molarmass="60.05"/> 
     <Component name="b" id="bbb" molarmass="18.02"/> 
     <Component name="c" id="ccc" molarmass="32.04"/> 
     <Component name="d" id="ddd" molarmass="46.03"/> 
    </Components> 
    ... 
</Model> 

和類

public class ChemieComponent 
{ 
    public string Name { get; set; } 
    public string Id { get; set; } 
    public double MolarMass { get; set; } 
} 

我與LINQ查詢可以解析這個組件對象?怎麼樣?我最終應該有一個IEnumerable,對吧?

編輯

<Points> 
    <Point name="P1" pressure="1"> 
    <Fractions> 
     <Fraction id="aaa" value="0.15272159"/> 
     <Fraction id="bbb" value="0.15272159"/> 
    </Fractions> 
    more points... 
</Points> 

回答

19

您可以使用以下方法:

XDocument doc = XDocument.Parse(xml); 
IEnumerable<ChemieComponent> result = from c in doc.Descendants("Component") 
             select new ChemieComponent() 
             { 
              Name = (string)c.Attribute("name"), 
              Id = (string)c.Attribute("id"), 
              MolarMass = (double)c.Attribute("molarmass") 
             }; 

編輯

訪問使用LINQ到XML嵌套的元素也可以:

public class Point 
{ 
    public string Name { get; set; } 
    public int Pressure { get; set; } 

    public IEnumerable<Fraction> Fractions { get; set; } 
} 

public class Fraction 
{ 
    public string Id { get; set; } 
    public double Value { get; set; } 
} 

static void Main() 
{ 
    string xml = @"<Points> 
     <Point name='P1' pressure='1'> 
      <Fractions> 
       <Fraction id='aaa' value='0.15272159'/> 
       <Fraction id='bbb' value='0.15272159'/> 
      </Fractions> 
     </Point> 
     </Points>"; 

    XDocument doc = XDocument.Parse(xml); 
    IEnumerable<Point> result = from c in doc.Descendants("Point") 
           select new Point() 
           { 
            Name = (string)c.Attribute("name"), 
            Pressure = (int)c.Attribute("pressure"), 
            Fractions = from f in c.Descendants("Fraction") 
               select new Fraction() 
               { 
                Id = (string)f.Attribute("id"), 
                Value = (double)f.Attribute("value"), 
               } 
           }; 
} 
+0

可能要檢查null或您的應用程序會爆炸。 –

+0

@Wouter:謝謝!這很好。我可以進行子查詢嗎?或者將不得不提出兩個疑問?看到我的編輯請 –

+0

@PedroDusso我已經添加了一些嵌套選擇代碼 –

4

我意識到這是一箇舊帖子,但我最近在做一些XML讀取的對象。我對Linq並不熱衷於XML - 它不太可讀,依賴於「魔術字符串」,並且如果XML模式更改,則需要更改代碼。

對於任何感興趣的人,我使用XmlSerializer類將XML反序列化爲對象。把反串行化代碼爲通用輔助方法,瞧 - 一個代碼行反序列化的XML文件轉換成一個對象圖: -

using System.IO; 
using System.Xml.Serialization; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var xml = @"<?xml version='1.0' encoding='utf-8' ?> 
      <Model> 
       <Points> 
        <Point name='P1' pressure='1'> 
         <Fractions> 
          <Fraction id='aaa' value='0.15272159'/> 
          <Fraction id='bbb' value='0.15272159'/> 
         </Fractions> 
        </Point> 
       </Points> 
      </Model>"; 

     var model = DeserializeObject<Model>(xml); 
    } 

    private static T DeserializeObject<T>(string xml) 
    { 
     var serializer = new XmlSerializer(typeof(T)); 
     using (var tr = new StringReader(xml)) 
     { 
      return (T)serializer.Deserialize(tr); 
     } 
    } 
} 

public class Model 
{ 
    [XmlArrayItem("Point")] 
    public Point[] Points { get; set; } 
} 

public class Point 
{ 
    [XmlAttribute(AttributeName = "name")] 
    public string Name { get; set; } 

    [XmlAttribute(AttributeName = "pressure")] 
    public int Pressure { get; set; } 

    [XmlArrayItem("Fraction")] 
    public Fraction[] Fractions { get; set; } 
} 

public class Fraction 
{ 
    [XmlAttribute(AttributeName = "id")] 
    public string Id { get; set; } 

    [XmlAttribute(AttributeName = "value")] 
    public double Value { get; set; } 
} 

甲警告夫婦: -

將該溶液明顯依賴在使用XML屬性裝飾領域模型時,您可能會也可能不會接受這些屬性。該解決方案還依賴於XML中存在的外部元素,如果根元素是數組(在本例中爲<Points>),則該方法不起作用。

無法指定IEnumerable<>(OP提到);你可以使用數組或List<>