我试图从xml文档中选择一个XElement并在xml文档的两个“级别”上进行匹配。我的文件结构是:
<app>
<Library Name="Main" Path="C:\somefile.Xml">
<ReadingList Name="Test1">
<Book>...
<ReadingList Name="Test2">
<Book>...
<Library Name="Backup" Path="C:\somefile.Xml">
而且我想在“ Main”库中找到阅读列表名称“ test2”,以便可以将此元素和所有子元素复制到另一个“ Library”节点。
在尝试学习此方法时,我希望使用linq解决方案。
预先感谢您的任何帮助
当我添加一个新的“阅读列表”时,我会这样做:
public void AddReadingList(string fullyQualifiedPath, Library lib, string name)
{
XDocument xdoc = XDocument.Load(fullyQualifiedPath);
XElement library = xdoc.Element("eStack").Elements("Library")
.Single(x => x.Attribute("Name").Value == lib.Name);
library.Add(new XElement("ReadingList", new XAttribute("Name", name)));
xdoc.Save(fullyQualifiedPath);
}
但是我要执行的操作是此元素和子元素的副本。问题是,可能有多个具有相同名称的“库”元素,因此我需要检查库名称和阅读列表名称。那有意义吗?
使用.Descendants
和Where
的组合将达到目的:
var result = XDocument.Load(fullyQualifiedPath)
.Descendants("Library")
//Can replace with `FirstOrDefault` if you know there is only one
.Where(element => element.Attribute("Name")?.Value == "Main")
.Descendants("ReadingList")
.Where(element => element.Attribute("Name")?.Value == "Test2").ToList();
您也可以.Elements
代替Descendants
我只是喜欢使用它,这样一来就不会同时指定app
或任何其他级别。
对于以前的c#6.0,您可以执行以下操作:
var result = XDocument.Load("data.xml")
.Descendants("Library")
.Where(element =>
{
var att = element.Attribute("Name");
return att != null ? (att.Value == "Main" ? true : false) : false;
})
.Descendants("ReadingList")
//Make sure to do above change here too
.Where(element => element.Attribute("Name")?.Value == "Test2").ToList();
或者,如果创建一种方法来帮助解决问题,而不是重复执行代码:
Func<XElement, string, string> tryGetAttributeValue = (element, attributeName) =>
{
var attribute = element.Attribute(attributeName);
return attribute == null ? string.Empty : attribute.Value;
};
var result = XDocument.Load("data.xml")
.Descendants("Library")
.Where(element => tryGetAttributeValue(element,"Name") == "Main")
.Descendants("ReadingList")
.Where(element => tryGetAttributeValue(element, "Name") == "Test2").ToList();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句