手动将XElement解析为自定义对象的最佳方法是什么?

时间:2009-06-04 09:51:22

标签: c# xml parsing

我有一个名为 content 的XElement变量,它包含以下XML:

<content>
    <title>Contact Data</title>
    <p>This is a paragraph this will be displayed in front of the first form.</p>
    <form idCode="contactData" query="limit 10; category=internal"/>
    <form idCode="contactDataDetail" query="limit 10; category=internal">
        <title>Contact Data Detail</title>
        <description>This is the detail information</description>
    </form>
</content>

我现在想简单地遍历每个1级节点并将它们解析为对象。回到C#2.0我用 XmlReader 来做这个,检查节点的类型,并相应地解析它。

但用LINQ 解析XML节点的最佳方法是什么,我希望这样:

var contentItems = from contentItem in pageItem.content.DescendantNodes()
                   select new ContentItem
                   {
                       Type = contentItem.Element()
                   };

foreach (var contentItem in contentItems)
{
    switch (contentItem.Type)
    {
        case "title":
            ...(parse title)...
        case "p":
            ...(parse p)...
        case "form":
            ...(parse form)...
    }
}

其中:

public class ContentItem
{
    public string Type { get; set; }
    public string IdCode { get; set; }
    public XElement Content { get; set; }
}

3 个答案:

答案 0 :(得分:2)

是否必须XElement?我会(手动或通过xsd.exe)创建映射到元素/属性名称的类 - 并使用XmlSerializer - 特别是通过StringReader

        Content content;
        using(StringReader sr = new StringReader(xml))
        using(XmlReader xr = XmlReader.Create(sr)) {
            XmlSerializer ser = new XmlSerializer(typeof(Content));
            content = (Content)ser.Deserialize(xr);
        }

(编辑)

使用实体类:

[XmlRoot("content")]
public class Content {
    [XmlElement("title")]
    public string Title { get; set; }
    [XmlElement("p")]
    public string Description { get; set; }
    [XmlElement("form")]
    public List<ContentForm> Forms { get; set; }
}    
public class ContentForm {
    [XmlAttribute("idCode")]
    public string Id { get; set; }
    [XmlAttribute("query")]
    public string Query { get; set; }
    [XmlElement("title")]
    public string Title { get; set; }
    [XmlElement("description")]
    public string Description { get; set; }
}

答案 1 :(得分:1)

我建议继承XElement,并为你想要的东西实现属性。 这些属性不应使用支持字段,而应直接使用基础XML元素。这样,您就可以使对象与XML保持同步。

答案 2 :(得分:0)

使用XML到LINQ,可以从XML中提取特定数据项,而不是通过XML迭代查找找到的内容。

var results = from node in XmlDocument.SomeContext(...)
              select new MyType {
                Prop1 = node.Element("One").Value,
                Prop2 = node.Element("One").Attributes().Where(
                      a => A.Value.Contains("Foo").Value
            };

如果需要条件,则可以使用(扩展)方法和任意表达式(null-coalescing operator,??,对默认值非常有用)。