C# Linq XML子体在枚举时丢失
我有这样一个XML文档C# Linq XML子体在枚举时丢失,c#,xml,linq,xml-parsing,C#,Xml,Linq,Xml Parsing,我有这样一个XML文档 <root> <item id="1" creator="me"> <childA>1</childA> <childB>2</childB> </item> <item id="2" creator="me"> <childA>1</childA> <childB>3</childB>
<root>
<item id="1" creator="me">
<childA>1</childA>
<childB>2</childB>
</item>
<item id="2" creator="me">
<childA>1</childA>
<childB>3</childB>
<childB>4</childB>
</item>
</root>
XDocument XmlRoot //whatever...you get the point
// Get item nodes
var items = XmlRoot.Descendants("item");
// Find duplicate items keys using creator attribute
var duplicateItemKeys = items.GroupBy(x => x.Attribute("creator").Value)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
foreach(var duplicateItemKey in duplicateItemKeys)
{
// Get the duplicate item XML elements using the duplicate keys
var duplicateItems = items.Where(x => x.Attribute("creator").Value == duplicateToucheKey)
.OrderBy(xelement => xelement.Attribute("CreatedOn").Value);
}
这是可行的,但是当我稍后尝试使用duplicateItems时会出现问题。任何时候它枚举(就像在foreach duplicateItems中)第一个项都会释放其子项的上下文。第二个很好
例如,在后面的代码中,我说
var allItemB = new List<XElement>();
foreach (duplicateItem in duplicateItems)
{
allItemB.AddRange(duplicateItem.Descendants("childB"));
}
var allItemB=new List();
foreach(duplicateItems中的duplicateItem)
{
allItemB.AddRange(duplicateItem.subjects(“childB”));
}
我希望“allItemB”在第一次传递时包含2,然后在第二次传递时包含234。最终的结果是它只包含34个元素,因为一旦duplicateItems数组被枚举,第一个XElement就会释放它的子元素
有人知道如何解决这个问题吗?如果我正确理解您的问题,您希望allItemB包含3个元素-allItemB[0]是值为2、[1]为3、[2]为4的XElement childB 如果是这样,问题是您在何处声明重复项。您的代码甚至不会编译,因为变量的作用域仅限于第一个foreach循环,因此在第二个foreach循环中不可用 获取上述结果的我的代码:
XDocument XmlRoot = XDocument.Load( "C:\\somefile.xml" );
// Get item nodes
var items = XmlRoot.Descendants("item");
// Find duplicate items keys using creator attribute
var duplicateItemKeys = items.GroupBy(x => x.Attribute("creator").Value)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
IEnumerable<XElement> duplicateItems = new List<XElement>();
foreach(var duplicateItemKey in duplicateItemKeys)
{
// Get the duplicate item XML elements using the duplicate keys
duplicateItems = items.Where(x => x.Attribute("creator").Value == duplicateItemKey)
.OrderBy(xelement => xelement.Attribute("id").Value);
}
var allItemB = new List<XElement>();
foreach (var duplicateItem in duplicateItems)
{
allItemB.AddRange(duplicateItem.Descendants("childB"));
}
XDocument XmlRoot=XDocument.Load(“C:\\somefile.xml”);
//获取项目节点
var items=XmlRoot.substands(“item”);
//使用“创建者”属性查找重复的项目密钥
var duplicateItemKeys=items.GroupBy(x=>x.Attribute(“创建者”).Value)
.Where(g=>g.Count()>1)
.选择(g=>g.Key);
IEnumerable duplicateItems=新列表();
foreach(duplicateItemKeys中的var duplicateItemKey)
{
//使用重复键获取重复项XML元素
duplicateItems=items.Where(x=>x.Attribute(“创建者”).Value==duplicateItemKey)
.OrderBy(xelement=>xelement.Attribute(“id”).Value);
}
var allItemB=新列表();
foreach(duplicateItems中的var duplicateItem)
{
allItemB.AddRange(duplicateItem.subjects(“childB”));
}
Edit:忘记提到我在第一个foreach循环中更改了OrderBy,因为示例xml文件没有CreatedOn属性
如果您愿意,您可以使用更多的Linq并完全删除foreach循环,如下所示:
XDocument XmlRoot = XDocument.Load( "C:\\somefile.xml" );
// Get item nodes
var items = XmlRoot.Descendants("item");
// Find duplicate items keys using creator attribute
var duplicateItemKeys = items.GroupBy(x => x.Attribute("creator").Value)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
// Get the duplicate item XML elements using the duplicate keys
var duplicateItems = items.Where(i => duplicateItemKeys.Contains(i.Attribute("creator").Value))
.OrderBy( xelement => xelement.Attribute("id").Value );
// Get the child nodes named childB
var allItemB = new List<XElement>();
allItemB.AddRange( duplicateItems.Descendants("childB") );
XDocument XmlRoot=XDocument.Load(“C:\\somefile.xml”);
//获取项目节点
var items=XmlRoot.substands(“item”);
//使用“创建者”属性查找重复的项目密钥
var duplicateItemKeys=items.GroupBy(x=>x.Attribute(“创建者”).Value)
.Where(g=>g.Count()>1)
.选择(g=>g.Key);
//使用重复键获取重复项XML元素
var duplicateItems=items.Where(i=>duplicateItemKeys.Contains(i.Attribute(“creator”).Value))
.OrderBy(xelement=>xelement.Attribute(“id”).Value);
//获取名为childB的子节点
var allItemB=新列表();
allItemB.AddRange(duplicateItems.subjects(“childB”);
第一部分的预期结果是什么?它必须保持为一个XElement,还是可以是一个“child”、“concatenated”的字典?理想情况下,我尝试解析XML中的重复项,然后重新组装并将其发送回数据库。什么是重复项?重复的标记名、值、属性名、属性值?两个重复项,由重复的创建者通过重复的标记名获得。尝试为合并场景解开重复对象。是的,我的代码没有编译,因为我错误地复制和粘贴了其他代码。很抱歉。我不敢相信我没有注意到duplicateItems变量的范围不正确!我觉得自己像个傻瓜。谢谢你的帮助!