[英]Linq to XML: parse some elements and skip some elements
我正在尝试使用Linq to XML
从XDocument
实例解析Linq to XML
,并将其存储在IEnumerable<MyClass>
。 我不想从xml文档中获取每个元素,因此我正在使用ElementAt(#index)
来获取值。 但是有时我想要的元素不在文档中,然后索引超出范围异常。 有没有更好的方法可以解析此文档中的值? 这是代码:
XML文档如下所示:
<someotherelement> /* I dont want the "someotherelement" part either */
<subelement></subelement>
<subelement></subelement>
</someotherelement>
<result>
<doc>
<int name="personid">8394</int> /* I don't want this value so I am skipping it */
<str name="name">James</str>
<str name="address">30 Awesome Lane</str>
<arr name="randomearray"> /* I want to skip this too */
<str name="random1">SomeValue</str>
<str name="random2">SomeValue</str>
<str name="random2">SomeValue</str>
</arr>
<str name="city">Awesome City</str>
<str name="state">CA</str>
<int name="zipcode">84392</int>
<str name="country">USA</str>
<str name="phonenumber">8309933820</str>
<date name="reportdate">2012-07-27T06:01:05.256Z</date>
</doc>
/* This is missing address and country */
<doc>
<int name="personid">10394</int> /* I don't want this value so I am skipping it */
<str name="name">Mathew</str>
<arr name="randomearray"> /* I want to skip this too */
<str name="random1">SomeValue</str>
<str name="random2">SomeValue</str>
<str name="random2">SomeValue</str>
</arr>
<str name="city">Not Awesome City</str>
<str name="state">CA</str>
<str name="zipcode">58439</str>
<str name="phonenumber">8309933820</str>
<date name="reportdate">2012-07-27T06:01:05.256Z</date>
</doc>
</result>
类:
public class Doc
{
public string Name {get;set;}
public string Address{get;set;}
public string City {get;set;}
public string State {get;set;}
public int ZipCode {get;set;}
public string Country {get;set;}
public string PhoneNumber {get;set;}
public DateTime ReportDate {get;set;}
}
Linq转Xml
string pathToXml = "http://www.foo.com/something";
var doc = XDocument.Load(pathToXml);
IEnumerable<Doc> myDoc = from item in doc.Descendants("doc")
select new Doc
{
Name = item.Element("str").Value,
Address = item.Element("str").ElementsAfterSelf("str").First().Value,
City = item.Element("str").ElementsAfterSelf("str").ElementAt(1).Value,
State = item.Element("str").ElementsAfterSelf("str").ElementAt(2).Value,
ZipCode = Convert.ToInt32(item.Element("int").Value)
Country = item.Element("str").ElementsAfterSelf("str").ElementAt(3).Value,
PhoneNumber = item.Element("str").ElementsAfterSelf("str").ElementAt(4).Value,
ReportDate = Convert.ToDateTime(item.Element("date").Value)
};
您可能希望使用XPath ,它使您可以更舒适地指定元素,例如使用它们的属性值,这在您的情况下似乎很有用。
与扩展方法结合使用以避免重复的语句:
public static string GetElementValue(this XElement element, string query)
{
var elem = element.XPathSelectElement(query);
return elem == null ? null : elem.Value;
}
一个例子:
select new Doc
{
Name = item.GetElementValue("str[@name='name']"),
...
}
我通过添加扩展方法来解决此问题:
public static class Extensions {
public static string GetValue(this XElement element) {
return element == null ? null : element.Value;
}
}
然后使用基于Attribute()
的值选择:
IEnumerable<Doc> myDoc = from item in doc.Descendants("doc")
select new Doc
{
Name = item.Element("str").Value,
Address = item.Element("str").ElementsAfterSelf("str").First().Value,
City = item.Element("str").ElementsAfterSelf("str").Where(el => (string)el.Attribute("name") == "city").FirstOrDefault().GetValue(),
State = item.Element("str").ElementsAfterSelf("str").Where(el => (string)el.Attribute("name") == "state").FirstOrDefault().GetValue(),
ZipCode = Convert.ToInt32(item.Element("int").Value),
Country = item.Element("str").ElementsAfterSelf("str").Where(el => (string)el.Attribute("name") == "country").FirstOrDefault().GetValue(),
PhoneNumber = item.Element("str").ElementsAfterSelf("str").Where(el => (string)el.Attribute("name") == "phonenumber").FirstOrDefault().GetValue(),
ReportDate = Convert.ToDateTime(item.Element("date").Value)
};
该扩展方法可能内置了一个,但我所不知道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.