Каков наилучший способ вручную проанализировать XElement на пользовательские объекты?

2

У меня есть переменная 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 и проанализировать их на объекты. В С# 2.0 я использую это с помощью XmlReader, проверьте тип node и проанализируйте его соответствующим образом.

Но какой лучший способ проанализировать узлы 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; }
}
  • 0
    Где именно вы разбираете? Например, когда вы анализируете заголовок ... куда вы хотите добавить значение "Контактные данные"?
  • 0
    Когда я анализирую титульный узел, тогда «Данные контакта» будут добавлены в UserControl как TextBlock. Когда я анализирую узел формы, из базы данных загружается и отображается форма с idCode = "contactData" и т. Д.
Теги:
parsing

3 ответа

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

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

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

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

  • 0
    Значит ли это, что если порядок важен, то LINQ действительно нельзя использовать для анализа XML? Например, в приведенном выше примере важно, чтобы «title» анализировался перед «p», поскольку именно так они будут выглядеть при вставке в TextBlocks в UserControl.
  • 0
    @Edward: Произвольные связи узлов можно проверить с помощью более сложных выражений LINQ или XPath. Но потребуется более подробная информация, чтобы привести пример (например, что произойдет, если p не следует за заголовком?)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню