【问题标题】:reading CDATA with linq to xml使用 linq to xml 读取 CDATA
【发布时间】:2009-05-01 02:28:51
【问题描述】:

我有以下 xml 文件,但似乎无法弄清楚如何获取元素中的值(这些元素隐藏在 CDATA 中)。我正在尝试为此使用 linq to 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>

【问题讨论】:

    标签: .net xml linq linq-to-xml


    【解决方案1】:

    问题在于命名空间 - 例如,类似:

    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
    

    【讨论】:

    • 事实证明这正是我的问题。感谢您帮助我解决这个问题,我对这个问题完全感到困惑。
    【解决方案2】:

    假设您的 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
    }
    

    我无法使用机器进行测试,因此我不做任何保证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      相关资源
      最近更新 更多