Question

J'ai le fichier XML suivant et n'arrive pas à comprendre comment obtenir la valeur dans les éléments (qui sont enfouis dans un CDATA). J'essaie d'utiliser linq to xml pour cela. Si quelqu'un sait comment convertir cela en un "Produit" object (supposons que nous ayons un objet produit qui possède des propriétés portant le même nom que les éléments). Merci d'avance.

bob

<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>
Était-ce utile?

La solution

Le problème concerne les espaces de noms - par exemple, quelque chose comme:

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"),
};

Vous pouvez également préférer XmlSerializer , par exemple:

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

Avec des définitions de classe telles que:

[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;}
}

Ou bien, exécutez simplement le code XML à l'aide de xsd.exe pour obtenir le code C # qui vous convient:

xsd foo.xml
xsd foo.xsd /classes

Autres conseils

En supposant que votre constructeur Product ait le constructeur utilisé ici, essayez ceci, où rawXml est le code XML de réponse CNET:

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
}

Je n'ai pas accès à une machine sur laquelle tester cela, je ne donne donc aucune garantie.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top