Linq to XML 创建具有唯一父元素的元素
Linq to XML create elements with unique parent
使用此 Linq 语句创建 XML
new XElement(ns + "SpecialRegisters",
from reg in registers
where reg.IsUpdateRegister
select new XElement(ns + "UpdateRegisters",
new XElement(ns + "RegID",
new XAttribute("ID", registers.IndexOf(reg).ToString().PadLeft(2, '0'))
)
)
)
是否可以创建具有多个 RegID 的唯一 UpdateRegisters 元素。
如果没有更新寄存器,则不应存在任何 UpdateRegisters 元素。
您可以这样做:
var result=new XElement(ns + "SpecialRegisters");
var updateRegister=register.Where(e=>e.IsUpdateRegister);// To not repeat the same query twice
if(updateRegister.Count()>0)
{
result.Add( new XElement(ns + "UpdateRegisters",
updateRegister.Select((e,i)=> new XElement(ns + "RegID",i));
}
更新
如果您想在同一条语句中完成所有操作,那么您可以这样做:
var updateRegister=register.Where(e=>e.IsUpdateRegister);// To not repeat the same query twice
var result=new XElement(ns + "SpecialRegisters", updateRegister.Any()?
new XElement(ns + "UpdateRegisters", updateRegister.Select((e,i)=> new XElement(ns + "RegID",i)):null );
我的解决方案基于你的 (miguelmpn)
速度并不重要,因为我正在保存一个简单的小文件..
new XElement(ns + "SpecialRegisters", Registers.Registers.Singleton.Any(x => x.IsUpdateRegister) ?
new XElement(ns + "UpdateRegisters", Registers.Registers.Singleton.Where(e => e.IsUpdateRegister).Select((e, i)=> new XElement(ns + "RegID", i))) : null)
我认为 Enumerable.Aggregate 方法重载之一非常适合这项任务。
var specialRegisters =
new XElement(ns + "SpecialRegisters",
Registers.Registers.Singleton.Where(reg => reg.IsUpdateRegister)
.Select((reg, i) => new XElement(ns + "RegID", i))
.Aggregate(new XElement(ns + "UpdateRegisters"),
(upReg, reg) =>
{
upReg.Add(reg);
return upReg;
},
upReg => upReg.HasElements ? upReg : null));
这种方法只会枚举集合一次。
Aggregate
方法的第三个参数是此方法的关键值,return null
如果没有添加任何元素。
我自己的评论意见:但我的意图是通过将所有代码都放在同一个 linq 查询中来保持代码更清晰。
我认为将这种逻辑保留在一个语句中不是干净的方法。我认为清洁的一个想法是 reader 你的代码会更快地理解你的意图。
您可以将创建 UpdateRegisters
元素提取到专用方法
private XElement CreateUpdateRegistersOrNullIfEmpty(XNamespace ns,
IEnumerable<YourType> data)
{
return data.Where(reg => reg.IsUpdateRegister)
.Select((reg, i) => new XElement(ns + "RegID", i))
.Aggregate(new XElement(ns + "UpdateRegisters"),
(upReg, reg) =>
{
upReg.Add(reg);
return upReg;
},
upReg => upReg.HasElements ? upReg : null));
}
那就用吧
var specialRegisters =
new XElement(ns + "SpecialRegisters",
CreateUpdateRegistersOrNullIfEmpty(ns, Registers.Registers.Singleton));
使用此 Linq 语句创建 XML
new XElement(ns + "SpecialRegisters",
from reg in registers
where reg.IsUpdateRegister
select new XElement(ns + "UpdateRegisters",
new XElement(ns + "RegID",
new XAttribute("ID", registers.IndexOf(reg).ToString().PadLeft(2, '0'))
)
)
)
是否可以创建具有多个 RegID 的唯一 UpdateRegisters 元素。 如果没有更新寄存器,则不应存在任何 UpdateRegisters 元素。
您可以这样做:
var result=new XElement(ns + "SpecialRegisters");
var updateRegister=register.Where(e=>e.IsUpdateRegister);// To not repeat the same query twice
if(updateRegister.Count()>0)
{
result.Add( new XElement(ns + "UpdateRegisters",
updateRegister.Select((e,i)=> new XElement(ns + "RegID",i));
}
更新
如果您想在同一条语句中完成所有操作,那么您可以这样做:
var updateRegister=register.Where(e=>e.IsUpdateRegister);// To not repeat the same query twice
var result=new XElement(ns + "SpecialRegisters", updateRegister.Any()?
new XElement(ns + "UpdateRegisters", updateRegister.Select((e,i)=> new XElement(ns + "RegID",i)):null );
我的解决方案基于你的 (miguelmpn)
速度并不重要,因为我正在保存一个简单的小文件..
new XElement(ns + "SpecialRegisters", Registers.Registers.Singleton.Any(x => x.IsUpdateRegister) ?
new XElement(ns + "UpdateRegisters", Registers.Registers.Singleton.Where(e => e.IsUpdateRegister).Select((e, i)=> new XElement(ns + "RegID", i))) : null)
我认为 Enumerable.Aggregate 方法重载之一非常适合这项任务。
var specialRegisters =
new XElement(ns + "SpecialRegisters",
Registers.Registers.Singleton.Where(reg => reg.IsUpdateRegister)
.Select((reg, i) => new XElement(ns + "RegID", i))
.Aggregate(new XElement(ns + "UpdateRegisters"),
(upReg, reg) =>
{
upReg.Add(reg);
return upReg;
},
upReg => upReg.HasElements ? upReg : null));
这种方法只会枚举集合一次。
Aggregate
方法的第三个参数是此方法的关键值,return null
如果没有添加任何元素。
我自己的评论意见:但我的意图是通过将所有代码都放在同一个 linq 查询中来保持代码更清晰。
我认为将这种逻辑保留在一个语句中不是干净的方法。我认为清洁的一个想法是 reader 你的代码会更快地理解你的意图。
您可以将创建 UpdateRegisters
元素提取到专用方法
private XElement CreateUpdateRegistersOrNullIfEmpty(XNamespace ns,
IEnumerable<YourType> data)
{
return data.Where(reg => reg.IsUpdateRegister)
.Select((reg, i) => new XElement(ns + "RegID", i))
.Aggregate(new XElement(ns + "UpdateRegisters"),
(upReg, reg) =>
{
upReg.Add(reg);
return upReg;
},
upReg => upReg.HasElements ? upReg : null));
}
那就用吧
var specialRegisters =
new XElement(ns + "SpecialRegisters",
CreateUpdateRegistersOrNullIfEmpty(ns, Registers.Registers.Singleton));