如何解决使用Linq到XML处理父子关系的子代
|| 我是新手,想学习LINQ to XML并遇到“儿童”问题。我有一个有关文档信息的XML文件;每个文档都有一些INDEX元素,如以下代码片段所示:<DOCUMENTCOLLECTION>
<DOCUMENT>
<FILE filename=\"Z:\\Consulting\\ConverterRun4\\B0000001\\Submission\\D003688171.0001.tif\" outputpath=\"Z:\\Consulting\\ConverterRun4\\B0000001\\Submission\"/>
<ANNOTATION filename=\"\"/>
<INDEX name=\"CAN(idmDocCustom4)\" value=\"\"/>
<INDEX name=\"Comment(idmComment)\" value=\"GENERAL CORRESPONDENCE 11-6-96 TO 10-29-\"/>
<INDEX name=\"DiagnosticID(idmDocCustom5)\" value=\"983958-0006.MDB-2155504\"/>
<INDEX name=\"Document Class(idmDocType)\" value=\"Submission\"/>
<INDEX name=\"Original File Name(idmDocOriginalFile)\" value=\"40410.TIF\"/>
<INDEX name=\"Title(idmName)\" value=\"1997-12\"/>
<FOLDER name=\"/Accreditation/NCACIHE/1997-12\"/>
</DOCUMENT>
<DOCUMENT>
我只需要INDEX元素中的几个值-名称属性为:
Comment(idmComment)
Document Class(idmDocType)
Title(idmName)
到目前为止,这是我的测试内容:
namespace ConsoleApplication1
{
class DocMetaData
{
public string Comment { get; set; }
public string Docclass { get; set; }
public string Title { get; set; }
public string Folder { get; set; }
public string File { get; set; }
}
class Program
{
static void Main(string[] args)
{
XDocument xmlDoc = XDocument.Load(@\"convert.B0000001.Submission.xml\");
List<DocMetaData> docList =
(from d in xmlDoc.Descendants(\"DOCUMENT\")
select new DocMetaData
{
Folder = d.Element(\"FOLDER\").Attribute(\"name\").Value,File = d.Element(\"FILE\").Attribute(\"filename\").Value,// need Comment,Docclass,Title from d.Element(\"INDEX\").Attribute(\"name\")
}
).ToList<DocMetaData>();
foreach (var c in docList)
{
Console.WriteLine(\"File name = {0}\",c.File);
Console.WriteLine(\"\\t\" + \"Folder = {0}\",c.Folder);
}
Console.ReadLine();
}
}
}
我不认为我在DocMetaData类中要加3。我想摆脱DOCUMENT中INDEX元素的一对多方面,并分配DocMetaData类中所示的属性。我无法理解如何处理这些孩子!
--------编辑更新---- 2011年5月27日----------------------
进行了以下更改,导致编译错误;已经研究了该错误并尝试对使用指令进行了一些重新安排,但到目前为止无法克服这一问题:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Linq;
namespace ConsoleApplication1
{
class DocMetaData
{
public string Comment { get; set; }
public string Docclass { get; set; }
public string Title { get; set; }
public string Folder { get; set; }
public string File { get; set; }
}
class Program
{
static void Main(string[] args)
{
XDocument xmlDoc = XDocument.Load(@\"convert.B0000001.Submission.xml\");
List<DocMetaData> docList =
(from d in xmlDoc.Descendants(\"DOCUMENT\")
select new DocMetaData
{
Folder = d.Element(\"FOLDER\").Attribute(\"name\").Value,Comment = d.Element(\"INDEX\")
.Where(i => i.Attribute(\"name\") == \"Comment(idmComment)\")
.First()
.Attribute(\"value\").Value
}
).ToList<DocMetaData>();
foreach (var c in docList)
{
Console.WriteLine(\"File name = {0}\",c.Folder);
Console.WriteLine(\"\\t\\t\" + \"Comment = {0}\",c.Comment);
}
Console.ReadLine();
}
这是错误(注意:我有System.Xml.Linq作为参考,也有using指令):
Error 1 \'System.Xml.Linq.XElement\' does not contain a deFinition for \'Where\' and no extension method \'Where\' accepting a first argument of type \'System.Xml.Linq.XElement\' Could be found (are you missing a using directive or an assembly reference?) C:\\ProjectsVS2010\\ConsoleApplication_LINQ\\ConsoleApplication1\\Program.cs 31 37 ConsoleApplication1
解决方法
您可能想要获取INDEX元素,然后使用
Where
和First
获得所需的元素。
select new DocMetaData
{
Folder = d.Element(\"FOLDER\").Attribute(\"name\").Value,File = d.Element(\"FILE\").Attribute(\"filename\").Value,Comment = d.Elements(\"INDEX\")
.Where(i => i.Attribute(\"name\").Value == \"Comment(idmComment)\")
.First()
.Attribute(\"value\").Value
//similarly for other index elements
}
请注意,如果没有具有right属性的INDEX元素,则将引发异常。如果要忽略没有相应索引的属性,我将选择代码放入其自己的方法中,使用FirstOrDefault
,并在分配之前进行适当的空检查。
,秘密在于SelectMany。这是一篇博客文章,可以帮助您解决问题。
http://craigwatson1962.wordpress.com/2010/11/04/linq-to-xml-using-let-yield-return-and-selectmany/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。