当多个元素具有相同的名称时,如何使用c#和XDocument将XML解析为一个对象?
我使用SharePoint 2013的REST API来解析XML,但解析某个XML块时遇到问题。下面是一个截短的XML示例,我可能会得到一些解析没有问题的XML:当多个元素具有相同的名称时,如何使用c#和XDocument将XML解析为一个对象?,c#,xml,sharepoint,C#,Xml,Sharepoint,我使用SharePoint 2013的REST API来解析XML,但解析某个XML块时遇到问题。下面是一个截短的XML示例,我可能会得到一些解析没有问题的XML: <feed xml:base="http://server/DesktopApplications/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m
<feed xml:base="http://server/DesktopApplications/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<id>2dff4586-6b7d-4186-ae63-4d048f74a112</id>
<title />
<updated>2014-03-19T15:32:15Z</updated>
<entry m:etag=""19"">
<id>http://server/DesktopApplications/_api/Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')</id>
<category term="SP.List" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')" />
<title />
<updated>2014-03-19T15:32:15Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:BaseTemplate m:type="Edm.Int32">101</d:BaseTemplate>
<d:BaseType m:type="Edm.Int32">1</d:BaseType>
<d:Id m:type="Edm.Guid">0ac46109-38d9-4070-96b7-f90085b56f1e</d:Id>
<d:ListItemEntityTypeFullName>SP.Data.Shared_x0020_DocumentsItem</d:ListItemEntityTypeFullName>
<d:Title>Documents</d:Title>
</m:properties>
</content>
</entry>
...
</feed>
当我展开查询以获取列表根文件夹的服务器相对url时,我得到的XML如下所示:
<feed xml:base="http://server/DesktopApplications/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<id>a01c22dc-a87f-4253-91d1-0a6ef8efa6d0</id>
<title />
<updated>2014-03-19T15:27:11Z</updated>
<entry m:etag=""19"">
<id>http://server/DesktopApplications/_api/Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')</id>
<category term="SP.List" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/RootFolder" type="application/atom+xml;type=entry" title="RootFolder" href="Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')/RootFolder">
<m:inline>
<entry>
<id>http://server/DesktopApplications/_api/Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')/RootFolder</id>
<category term="SP.Folder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="Web/Lists(guid'0ac46109-38d9-4070-96b7-f90085b56f1e')/RootFolder" />
<title />
<updated>2014-03-19T15:27:11Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:ServerRelativeUrl>/DesktopApplications/Shared Documents</d:ServerRelativeUrl>
</m:properties>
</content>
</entry>
</m:inline>
</link>
<title />
<updated>2014-03-19T15:27:11Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:BaseTemplate m:type="Edm.Int32">101</d:BaseTemplate>
<d:BaseType m:type="Edm.Int32">1</d:BaseType>
<d:Id m:type="Edm.Guid">0ac46109-38d9-4070-96b7-f90085b56f1e</d:Id>
<d:ListItemEntityTypeFullName>SP.Data.Shared_x0020_DocumentsItem</d:ListItemEntityTypeFullName>
<d:Title>Documents</d:Title>
</m:properties>
</content>
</entry>
...
</feed>
但这已经不起作用了。文档子体(m+“属性”)
返回的第一件事是
<m:properties>
<d:ServerRelativeUrl>/DesktopApplications/Shared Documents</d:ServerRelativeUrl>
</m:properties>
/桌面应用程序/共享文档
因此,试图同时设置其他属性会引发对象引用异常,因为其他元素不在这里
我如何解析这个XML,使我想要的所有值都进入一个对象?我宁愿不必单独打电话来获取每个列表的根文件夹url
更新:
我在下面贴了一个答案,但我觉得有更好的办法。如果答案比我的好,请随意发布,我会将你的标记为答案。你要做的是在获取元素值之前检查元素是否存在,因为目前你只是假设它们始终存在 在这里之前有人问过这个问题(我没有足够的声誉来发表评论):
我想出了一个办法来满足我的需求,但我觉得必须有更好的办法
private readonly XNamespace a = "http://www.w3.org/2005/Atom";
private readonly XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
private readonly XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
List<KLList> lists = doc.Descendants(a + "entry").Where(element => element.Attribute(m + "etag") != null).Select(
list => new KLList()
{
Id = list.Descendants(d + "Id").FirstOrDefault().Value,
Title = list.Descendants(d + "Title").FirstOrDefault().Value,
ListItemEntityTypeFullName = list.Descendants(d + "ListItemEntityTypeFullName").FirstOrDefault().Value,
BaseType = (BaseType)Convert.ToInt32(list.Descendants(d + "BaseType").FirstOrDefault().Value),
ListTemplateType = (ListTemplateType)Convert.ToInt32(list.Descendants(d + "BaseTemplate").FirstOrDefault().Value),
RelativeUrl = list.Descendants(d + "ServerRelativeUrl").FirstOrDefault().Value
}).ToList();
私有只读XA=”http://www.w3.org/2005/Atom";
私有只读XD=”http://schemas.microsoft.com/ado/2007/08/dataservices";
私有只读XM=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
列表列表=文档子体(a+“条目”)。其中(元素=>元素属性(m+“etag”)!=null)。选择(
list=>newkllist()
{
Id=list.subjects(d+“Id”).FirstOrDefault()值,
Title=list.substands(d+“Title”).FirstOrDefault()值,
ListItemEntityTypeFullName=list.subjects(d+“ListItemEntityTypeFullName”).FirstOrDefault()值,
BaseType=(BaseType)Convert.ToInt32(list.substands(d+“BaseType”).FirstOrDefault().Value),
ListTemplateType=(ListTemplateType)Convert.ToInt32(list.substands(d+“BaseTemplate”).FirstOrDefault().Value),
RelativeUrl=list.subjects(d+“ServerRelativeUrl”).FirstOrDefault()值
}).ToList();
但即使检查这些元素是否存在,也无法得到我想要的。我想要的所有这些值都存在于
下,但它们由
的两个元素分隔。我希望在一个对象中同时包含
下的所有内容。目前,通过迭代doc.subjects(m+“properties”)
将它们分开,这不是我想要的。这有意义吗?
<m:properties>
<d:ServerRelativeUrl>/DesktopApplications/Shared Documents</d:ServerRelativeUrl>
</m:properties>
private readonly XNamespace a = "http://www.w3.org/2005/Atom";
private readonly XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
private readonly XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
List<KLList> lists = doc.Descendants(a + "entry").Where(element => element.Attribute(m + "etag") != null).Select(
list => new KLList()
{
Id = list.Descendants(d + "Id").FirstOrDefault().Value,
Title = list.Descendants(d + "Title").FirstOrDefault().Value,
ListItemEntityTypeFullName = list.Descendants(d + "ListItemEntityTypeFullName").FirstOrDefault().Value,
BaseType = (BaseType)Convert.ToInt32(list.Descendants(d + "BaseType").FirstOrDefault().Value),
ListTemplateType = (ListTemplateType)Convert.ToInt32(list.Descendants(d + "BaseTemplate").FirstOrDefault().Value),
RelativeUrl = list.Descendants(d + "ServerRelativeUrl").FirstOrDefault().Value
}).ToList();