我该如何简化?
我有一个XML文件,如:
<Root>
<Header />
<Content />
<Content />
<Content />
<!-- …. Lots of Contents -->
<Footer />
</Root>
我需要拆分成较小的文件,以便每个文件都有一个'Header'和一个'Footer',然后X很多'Content'。 我当前的方法获取主文件的副本,删除所有内容,然后添加基于skip&amp;的所需内容。取。
我不喜欢它,因为我每次都会将原件复制到内存中,删除内容然后添加一些我刚删除的内容:
while (index < totalContents) {
var newXDoc = new XDocument(xDoc);
newXDoc.Descendants("Content").Remove();
newXDoc.Root.Element("Header").AddAfterSelf(
xDoc
.Descendants("Content")
.Skip(index)
.Take(ordersPerFile)
);
xmlDocs.Add(XmlConverter.ToXmlDocument(newXDoc));
index += ordersPerFile;
}
有更优雅的方式来执行此任务吗?
我正在寻找类似的东西:
while (index < totalContents) {
var newXDoc = new XDocument(
xDoc.Where(x => x.ContentElementsThatIWantForThisIteration...)
);
xmlDocs.Add(XmlConverter.ToXmlDocument(newXDoc));
index += ordersPerFile;
}
由于
答案 0 :(得分:4)
我会在中获取页眉和页脚 - 然后亲自使用MoreLINQ中的Batch
方法:
var header = doc.Root.Element("Header");
var footer = doc.Root.Element("Footer");
var contents = doc.Root.Elements("Contents");
var newDocs = contents.Batch(ordersPerFile)
.Select(middle => new XDocument(
new XElement("Root", header, middle, footer)))
.ToList();
如果您不想使用MoreLINQ,可以为所有内容创建List<XElement>
,然后使用Skip
/ Take
创建批次,或者显式获取它们按索引。 (Marcin的分组方法很好。)我建议使用MoreLINQ - 你可能会发现它在其他方面对你有用。
(免责声明:我启动了MoreLINQ项目,但从那时起它已经成长。虽然它可以通过Nuget package轻松安装。)
答案 1 :(得分:3)
您可以使用GroupBy
来模拟分页,这样就可以将它们放在一个查询中。
var header = xDoc.Root.Element("Header");
var footer = xDoc.Root.Element("Footer");
var contents = xDoc.Root.Elements("Content")
var newXDocs = contents.Select((c, i) => new { c, i })
.GroupBy(x => x.i / ordersPerFile)
.Select(x => new XDocument(
new XElement("Root",
header,
x.Select(y => y.c),
footer)))
.ToList();
顺便说一句。使用Descendants
使查询遍历整个XML树,因此最好使用Elements