XElement with LINQ Select 和可选元素
本文关键字:元素 Select with LINQ XElement | 更新日期: 2023-09-27 18:32:33
我正在尝试显示从外部服务获得的某些XML中的某个日期。我正在使用 XElement,并尝试使用 LINQ select 来获取我的数据。
var xElem = XElement.Load(HttpUtility.UrlPathEncode(url));
var books = (from pubs in xElem.Elements("result")
select new
{
Id = (string)pubs.Element("data").Element("id"),
Title = (string)pubs.Element("data").Element("title"),
Year = (string)pubs.Element("data").Element("year"),
Resources = (string)pubs.Element("data")
.Element("resource")
.Element("url")
.ElementValueNull(),
Authors= pubs.Element("data").Elements("person")
}).ToList();
foreach (var book in books)
{
// Put the string together with string builder....
foreach (var person in book.Authors)
{
//Get the authors
}
}
当然,我已经为ElementValueNull制作了类。
//This method is to handle if element is missing
public static string ElementValueNull(this XElement element)
{
if (element != null)
return element.Value;
return "";
}
//This method is to handle if attribute is missing
public static string AttributeValueNull(this XElement element, string attributeName)
{
if (element == null)
return "";
else
{
XAttribute attr = element.Attribute(attributeName);
return attr == null ? "" : attr.Value;
}
}
问题是带有其元素的资源标记并不总是存在。如果它不存在,它将跳过整个记录。有没有简单的方法可以使资源具有从我的类返回的空字符串,但仍使用 LINQ 选择添加记录?
使用 XML 进行编辑示例:
<?xml version="1.0" encoding="UTF-8"?>
<tester xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://tester.no/xmlSchema/xsd/tester.xsd">
<generert>2014-12-01</generert>
<result>
<data>
<id>297474</id>
<person>
<id>11690</id>
<surname>Medel-Svensson</surname>
<firstname>Ronnie</firstname>
</person>
<title>Title 1</title>
<year>2009</year>
</data>
</result>
<result>
<data>
<id>807059</id>
<person>
<id>11690</id>
<surname>Bronskimlet</surname>
<firstname>Hallstein</firstname>
</person>
<person>
<id>328009</id>
<surname>Kroksleiven</surname>
<firstname>Jostein</firstname>
</person>
<person>
<id>328010</id>
<surname>Gassolini</surname>
<firstname>Ruffino</firstname>
</person>
<person>
<id>327990</id>
<surname>von Schnellfahrer</surname>
<firstname>Heinrich</firstname>
</person>
<title>Title 2</title>
<year>2010</year>
<resource>
<type>
<code>TEXT</code>
</type>
<url>http://www.example.com/</url>
</resource>
</data>
</result>
<result>
<data>
<id>1164653</id>
<person>
<id>11690</id>
<surname>Bergsprekken</surname>
<firstname>Mysil</firstname>
</person>
<title>Title 3</title>
<year>2014</year>
<resource>
<type>
<code>FULLTEKST</code>
</type>
<url>http://www.example.com/</url>
</resource>
</data>
</result>
</tester>
有几件事:
-
如果使用
Element(..)
,则结果可能是null
。 如果路径中缺少元素,这可能会导致空引用异常。 处理此问题的更优雅方法是使用序列并返回一个元素(如果存在),请使用SingleOrDefault()
-
XElement
和XAttribute
都内置了一堆显式类型转换运算符。 这意味着您可以转换为string
和各种其他基元。 由于字符串是引用类型,如果XObject
为 null,它将返回null
。 在这种情况下,int
等值类型会引发异常,但int?
不会。
考虑到这一点,这样的事情应该可以解决您的问题。 请注意,由于"数据"是所有人共有的,因此您可以将其放在初始选择器中:
from pubs in xElem.Elements("result").Elements("data")
select new
{
Id = (string)pubs.Element("id"),
Title = (string)pubs.Element("title"),
Year = (string)pubs.Element("year"),
Resources = (string)pubs.Elements("resource")
.Elements("url")
.SingleOrDefault(),
Authors= pubs.Elements("person")
}