У меня есть переменная 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; }
}
Должно ли быть 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; }
}
Я бы предложил наследовать XElement и реализовать свойства для нужного вам материала. Эти свойства не должны использовать поддерживающие поля, а работать непосредственно с базовым элементом XML. Таким образом, вы сохраните объект в синхронизации с XML.
С 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
};
Если необходимы условия, могут использоваться методы (расширения) и произвольные выражения (оператор нулевой коалесцировки,??, может быть очень полезен для дефолта).