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: