C# 带有LINQ Select和可选元素的XElement
我试图显示从外部服务获取的XML中的一些日期。我正在使用XElement并尝试使用LINQ select获取数据C# 带有LINQ Select和可选元素的XElement,c#,xml,linq,C#,Xml,Linq,我试图显示从外部服务获取的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("
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 select添加记录
使用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>
有几件事:
- 如果使用
,则结果可能是元素(..)
。如果路径中缺少元素,这可能会导致空引用异常。处理此问题的一种更优雅的方法是使用序列,如果存在元素,则使用null
SingleOrDefault()
和XElement
都内置了一系列显式类型转换运算符。这意味着您可以强制转换为XAttribute
和各种其他原语。由于字符串是引用类型,如果字符串
为null,它将返回XObject
。在这种情况下,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")
}
您可以使用
XPath
快速、轻松地提取数据,但您应该向我们展示XML的格式。是的,我当然可以使用XPath,但我想使用LINQ尝试一下。查尔斯干杯。我把数据放在select之前的路径中,它看起来更干净。然而,使用SingleOrDefault尝试代码仍然只返回我正在尝试的3条记录中的2条。在没有资源的情况下省略记录。是否可以包含正在解析的xml的示例?虽然我认为我可能简化了XLinq
代码,但我认为“跳过”整个数据
元素的问题可能与您最初尝试的代码无关。如果它试图解析缺少资源的数据
元素,它应该抛出异常,而不是“跳过”异常。现在添加了XML示例。好的,我已经通过XElement.Load加载了XML。使用您的代码,我得到了一个空引用异常(正如我所期望的),使用我的代码,我得到了3项,其中一项的资源为null
。没有理由你应该得到2。对不起,查尔斯,在最初的帖子发布后,我一定把我这边的事情搞砸了。我刚开始用你的例子来解释SingleOrDefault,这一切看起来都很有魅力!非常感谢D