2016-09-28 42 views
3

我有如下的XML文件:如何使用LINQ解析XML將物體與的XDocument

<Message xsi:schemaLocation =".."> 
    <Header>..</Header> 
    <Body> 
     <History 
      xmlns=".."> 
      <Number></Number> 
      <Name></Name> 
      <Item> 
       <CreateDate>..</CreateDate> 
       <Type>..</Type> 
       <Description></Description> 
      </Item> 
      <Item> 
       <CreateDate>..</CreateDate> 
       <Type>..</Type> 
       <Description>1..</Description> 
       <Description>2..</Description> 
      </Item> 
     </History> 
    </Body> 
</Message> 

我想從這個創建和對象作爲歷史對象。

public class History 
{ 
    public string Name { get; set; } 
    public string Number { get; set; } 
    public List<Item> Items { get; set; } 

} 



    var xElement = XDocument.Parse(xmlString); 

    XElement body = (XElement)xElement.Root.LastNode; 
    XElement historyElement = (XElement)body.LastNode; 

    var history = new History 
    { 
     Name = (string)historyElement.Element("Name"), 
     Number = (string)historyElement.Element("Number"), 
     Items = (
       from e in historyElement.Elements("Item") 
       select new Item 
       { 
        CraeteDate = DateTime.Parse(e.Element("CreateDate").Value), 
        Type = (string)e.Element("Type").Value, 
        Description = string.Join(",", 
         from p in e.Elements("Description") select (string)p.Element("Description")) 
       }).ToList() 

    }; 

爲什麼這不起作用?

這些值始終爲空。

即使有元素和元素的值,「historyElement.Element(」Name「)」總是爲空。

任何想法我錯過了什麼?

感謝

回答

2

這是由於命名空間,嘗試這樣做:如果你想了解更多關於這個問題,看看這個link

+0

謝謝。是的,這是名字空間。 – akd

+0

不客氣;) – octavioccl

0

一對夫婦的小事情

XNamespace ns = "http://schemas.microsoft.com/search/local/ws/rest/v1";// the namespace you have in the history element 
var xElement = XDocument.Parse(xmlString); 

var history= xElement.Descendants(ns+"History") 
        .Select(historyElement=>new History{ Name = (string)historyElement.Element(ns+"Name"), 
                  Number = (string)historyElement.Element(ns+"Number"), 
                  Items = (from e in historyElement.Elements(ns+"Item") 
                    select new Item 
                      { 
                      CraeteDate= DateTime.Parse(e.Element(ns+"CreateDate").Value), 
                      Type = (string) e.Element(ns+"Type").Value, 
                      Description= string.Join(",", 
                      from p in e.Elements(ns+"Description") select (string)p) 
                      }).ToList() 
                  }).FirstOrDefault(); 

這裏,這裏的xml格式不正確。所以不得不花一些時間來測試並使其工作。

你在前面有一個xsi,我認爲它應該在xsd中提到的某處。

原來你有追加的命名空間,如果你的XML節點連接到它爲你解析XML樹在這裏命名空間:

我的樣品溶液是這樣的:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    public class History 
    { 
     public string Name { get; set; } 
     public string Number { get; set; } 
     public List<Item> Items { get; set; } 

    } 

    public class Item 
    { 
     public DateTime? CreateDate { get; set; } 
     public string Type { get; set; } 
     public string Description { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      string xmlString = 
       @"<Message> 
        <Header>..</Header> 
        <Body> 
         <History 
          xmlns=""http://schemas.somewhere.com/types/history""> 
          <Number>12</Number> 
          <Name>History Name</Name> 
          <Item> 
           <CreateDate></CreateDate> 
           <Type>Item 1 Type</Type> 
           <Description>Item 1 Description</Description> 
          </Item> 
          <Item> 
           <CreateDate></CreateDate> 
           <Type>Item 2 Type</Type> 
           <Description>Item 2 Description 1</Description> 
           <Description>Item 2 Description 2</Description> 
          </Item> 
         </History> 
        </Body> 
       </Message>"; 


      XNamespace ns = "http://schemas.somewhere.com/types/history"; 
      var xElement = XDocument.Parse(xmlString); 

      var historyObject = xElement.Descendants(ns +"History") 
       .Select(historyElement => new History 
       { 
        Name = historyElement.Element(ns + "Name")?.Value, 
        Number = historyElement.Element(ns + "Number")?.Value, 
        Items = historyElement.Elements(ns + "Item").Select(x => new Item() 
        { 
         CreateDate = DateTime.Parse(x.Element(ns + "CreateDate")?.Value), 
         Type = x.Element(ns + "Type")?.Value, 
         Description = string.Join(",", x.Elements(ns + "Description").Select(elem=>elem.Value)) 
        }).ToList() 
       }).FirstOrDefault(); 
     } 
    } 
} 

如果你不想關心尋找命名空間,你可能想嘗試以下:

var document = XDocument.Parse(xmlString); 
    var historyObject2 = document.Root.Descendants() 
     .Where(x=>x.Name.LocalName == "History") 
     .Select(historyElement => new History 
     { 
      Name = historyElement.Element(historyElement.Name.Namespace + "Name")?.Value, 
      Number = historyElement.Element(historyElement.Name.Namespace+ "Number")?.Value, 
      Items = historyElement.Elements(historyElement.Name.Namespace + "Item").Select(x => new Item() 
      { 
       //CreateDate = DateTime.Parse(x.Element("CreateDate")?.Value), 
       Type = x.Element(historyElement.Name.Namespace + "Type")?.Value, 
       Description = string.Join(",", x.Elements(historyElement.Name.Namespace + "Description").Select(elem => elem.Value)) 
      }).ToList() 
     }).FirstOrDefault();