[Silverlight入门系列]Silverlight读取XElement

Silverlight由于用的是Silverlight版的.NET Framework,不是完整版,所以在Silverlight下面处理xml有点不一样。XmlDocument没有了,取而代之的是XDocument,是Linq的东东,使用起来还是很方便的:

   1: XDocument xmlProducts = XDocument.Parse(xmlContent);
   2: var products = from product in xmlProducts.Descendants("Product")
   3:                   select new
   4:                    {
   5:                      ProductID = Convert.ToInt32(product.Element("ProductId").Value),
   6:                      ProductName = (string)product.Element("ProductName").Value
   7:                    }; 

XElement是XDocument下面的东东,XDocument可以添加它:

   1: StringBuilder output = new StringBuilder();
   2: XElement srcTree = new XElement("Root",
   3:     new XElement("Element1", 1),
   4:     new XElement("Element2", 2),
   5:     new XElement("Element3", 3),
   6:     new XElement("Element4", 4),
   7:     new XElement("Element5", 5)
   8: );
   9: XElement xmlTree = new XElement("Root",
  10:     new XElement("NewElement", "Content")
  11: );
  12: xmlTree.Add(
  13:     from el in srcTree.Elements()
  14:     where (int)el >= 3
  15:     select el
  16: );
  17: output.Append(xmlTree + Environment.NewLine);
  18:  
  19: OutputTextBlock.Text = output.ToString();

 

当然,XElement也可以从xml文件加载:

   1: private void Page_Loaded(object sender, RoutedEventArgs e)
   2: {
   3:     DataGrid1.ItemsSource = GetStatusReport();
   4: }
   5:  
   6: public List<Status> GetStatusReport()
   7: {
   8:     List<Status> statusReport = new List<Status>();
   9:  
  10:     XElement doc = XElement.Load(@"Data/StatusReport.xml");
  11:  
  12:     statusReport = (from el in doc.Elements()
  13:                     select GetStatus(el)).ToList();
  14:  
  15:     return statusReport;
  16: }
  17:  
  18: private Status GetStatus(XElement el)
  19: {
  20:     Status s = new Status();
  21:     s.Description = el.Attribute("Description").Value;
  22:     s.Date = DateTime.Parse(el.Attribute("Date").Value);
  23:     return s;
  24: }

 

在WCF Ria Service的DomainService可以返回一个XElement类型的数据,它比XDocument更便携:

   1: [Invoke]
   2: [RequiresAuthentication]
   3: public XElement TestDomainService(string param)
   4: {
   5:     var query = ... // linq query...
   6:     return query.Value.ToArray().AsXml(true).Root; //return XElement
   7: }

 

返回的XElement假设是这样的XML:

   1: <Shuttle xmlns="">
   2:   <shuttleVersion>0101</shuttleVersion>
   3:   <shuttleDate Name="CrashAT__01">
   4:     <job>CRASHME</job>
   5:     <param></param>
   6:     <startDateTime>0000000000</startDateTime>
   7:     <executeInterval>01</executeInterval>
   8:     <executeNext>0000000000</executeNext>
   9:     <errorRepetitionNumber>03</errorRepetitionNumber>
  10:     <errorRepetitionInterval>05</errorRepetitionInterval>
  11:     <currentErrorRepitionNumber>00</currentErrorRepitionNumber>
  12:     <shuttleListValue>0000</shuttleListValue>
  13:     <executeNextDetail>0000000000</executeNextDetail>
  14:     <shuttleListList>
  15:       <shuttleList Name="ALL_0100_0600">
  16:         <shuttleListWeekday>ALL</shuttleListWeekday>
  17:         <shuttleListStart>0100</shuttleListStart>
  18:         <shuttleListEnd>0600</shuttleListEnd>
  19:       </shuttleList>
  20:     </shuttleListList>
  21:   </shuttleDate>
  22: </Shuttle>

 

如何读取XElement?如何用递归把上面的XML转换为树形的无限极的实体类呢?最方便的当然是用xml.linq。另外一种方法是用XmlReader:

   1: using (var reader = XmlReader.Create(new StringReader(xmlElement.ToString(SaveOptions.None))))
   2: {
   3:     while (reader.Read())
   4:     {
   5:         if (reader.NodeType != XmlNodeType.Element) continue;
   6:  
   7:         //From 1st line to last line, including comments, EndElement...
   8:         //....        
   9:      }
  10: }    

 

无限递归XElement - XElement.Elements()

还有一种方法是递归XElement – XElment.Elements(),如果你需要把XElement转为树形复合结构的类列表(类下面有子类,无限层级),需要用这个方法:

   1: //入口函数
   2: private IEnumerable<<YourEntity> GetAllNodes(XElement element)
   3: {
   4:     IList<YourEntity> ret = new List<YourEntity>();
   5:     
   6:     foreach (var elem in element.Elements())
   7:     {
   8:         if (elem.HasElements)
   9:         {
  10:             var node = CreateNode(elem);
  11:            
  12:             foreach (var item in CreateNodeCollection(elem)) // 这里面有递归
  13:             {
  14:                 node.Children.Add(item);
  15:             }
  16:             ret.Add(node);
  17:         }
  18:         else
  19:         {
  20:             ret.Add(CreateNode(elem));
  21:         }
  22:     
  23:     }        
  24:     return ret;     
  25: }
  26:  
  27: //递归调用
  28: private IEnumerable<YourEntity> CreateNodeCollection(XElement element)
  29: {
  30:     IList<YourEntity> ret = new List<YourEntity>();
  31:  
  32:     foreach (XElement elem in element.Elements())
  33:     {
  34:         if (elem.HasElements)
  35:         {
  36:             var node = CreateNode(elem);
  37:             foreach (var item in CreateNodeCollection(elem))
  38:             {
  39:                 node.Children.Add(item);
  40:             }
  41:             ret.Add(node);
  42:         }
  43:         else
  44:         {
  45:             ret.Add(CreateNode(elem, param));
  46:         }
  47:     }
  48:     return ret;
  49: }
  50:         
  51: private YourEntity CreateNode(XElement element)
  52: {
  53:     var ret = new YourEntity();
  54:     ret.Name = element.Name.ToString();
  55:     ret.Value = element.Value;
  56:     ret.Tag = element.HasAttributes ? element.FirstAttribute.Value : element.Value;
  57:     return ret;
  58: }                    
  59:                     

posted @ 2011-09-22 16:05  Areas  阅读(261)  评论(0编辑  收藏  举报