2009-05-01 130 views
2

我有以下的XML文件,似乎無法弄清楚如何獲取元素(它們被埋在CDATA中)的值。我正在嘗試使用linq來爲此xml。如果有人知道如何將其轉換爲「Product」對象(假設我們有一個產品對象具有與元素名稱相同的屬性)。提前致謝。讀取CDATA與LINQ到XML

鮑勃

<CNETResponse realm="cnet" version="1.0" xmlns="http://api.cnet.com/rest/v1.0/ns" xmlns:xlink="http://www.w3.org/1999/xlink"> 
<TechProduct id="33517677"> 
    <Name><![CDATA[Nikon CoolPix L20 (deep red)]]></Name> 
    <Topic id="1670"></Topic> 
    <ImageURL width="60"><![CDATA[http://i.i.com.com/cnwk.1d/sc/33517677-2-60-0.gif]]></ImageURL> 
</TechProduct> 
</CNETResponse> 

回答

2

的問題是命名空間 - 例如,類似:

XNamespace ns = "http://api.cnet.com/rest/v1.0/ns"; 
XElement techProd = doc.Root.Element(ns + "TechProduct"); 

Product product = new Product { 
    Id = (int)techProd.Attribute("id"), 
    Name = techProd.Element(ns + "Name").Value, 
    Topic = techProd.Element(ns + "Topic").Value, 
    TopicId = (int)techProd.Element(ns + "Topic").Attribute("id"), 
    ImageUrl = techProd.Element(ns + "ImageURL").Value, 
    ImageWidth = (int)techProd.Element(ns + "ImageURL").Attribute("width"), 
}; 

您也可能更喜歡XmlSerializer - 是這樣的:

XmlSerializer ser = new XmlSerializer(typeof(CnetResponse)); 
CnetResponse response = (CnetResponse)ser.Deserialize(new StringReader(xml)); 
TechProduct product = response.TechProduct; 

有了這樣的類定義:

[Serializable, XmlRoot("CNETResponse", Namespace = CnetResponse.Namespace)] 
public class CnetResponse { 
    public const string Namespace = "http://api.cnet.com/rest/v1.0/ns"; 
    public TechProduct TechProduct { get; set; } 
} 
[Serializable, XmlType(Namespace = CnetResponse.Namespace)] 
public class TechProduct 
{ 
    [XmlAttribute("id")] 
    public int Id { get; set; } 
    public string Name {get;set;} 
    public Topic Topic { get; set; } 
    [XmlElement("ImageURL")] 
    public Image Image { get; set; }   
} 
[Serializable, XmlType(Namespace = CnetResponse.Namespace)] 
public class Topic { 
    [XmlAttribute("id")] 
    public int Id { get; set; } 
    [XmlText] 
    public string Text {get;set;} 
} 
[Serializable, XmlType(Namespace = CnetResponse.Namespace)] 
public class Image { 
    [XmlAttribute("width")] 
    public int Width { get; set; } 
    [XmlText] 
    public string Url {get;set;} 
} 

或者,也可以通過xsd.exe運行xml以獲取C#代碼西裝:

xsd foo.xml 
xsd foo.xsd /classes 
+0

原來,這正是我的問題在這裏。感謝您幫助我解決這個問題,我完全被這個問題困擾。 – Beaker 2009-05-03 20:37:22

1

假設你Product類有這裏使用的構造方法,試試這個,這裏rawXml是CNET響應XML:

XElement cnetResponse = XElement.Parse(rawXml); 

IEnumerable<NameQty> products = 
    from e in cnetResponse.Descendants("TechProduct") 
    select new Product(
     (string)e.Element("Name"), 
     (int)e.Element("Topic").Attribute("id"), 
     (string)e.Element("ImageURL") 
    ); 

foreach(Product p in products) 
{ 
    // do stuff 
} 

我有一臺機器不能訪問上爲了測試這個,所以我不作任何保證。