Каков наилучший способ вручную проанализировать XElement на пользовательские объекты? - PullRequest
2 голосов
/ 04 июня 2009

У меня есть переменная XElement с именем content , которая состоит из следующего 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 , проверяю тип узла и анализирую его соответственно.

Но каков наилучший способ анализа узлов XML с помощью LINQ , я ожидал бы что-то вроде этого:

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 ]

2 голосов
/ 04 июня 2009

Это должно быть 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 голос
/ 04 июня 2009

Я бы предложил наследовать XElement и реализовать свойства для того, что вам нужно. Эти свойства не должны использовать вспомогательные поля, а должны работать непосредственно с базовым элементом XML. Таким образом, вы будете синхронизировать объект с XML.

0 голосов
/ 04 июня 2009

При использовании 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
            };

Если необходимы условия, то можно использовать методы (расширения) и произвольные выражения (оператор слияния нуля ?? может быть очень полезным по умолчанию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...