我有一个看起来像这样的XML,
<Names>
<Name>
<FName>Abc</FName>
<LName>XYZ</LName>
</Name>
<Name>
<FName>Abc2</FName>
<LName>XYZ2</LName>
</Name>
<Name>
<FName>Abc3</FName>
<LName>XYZ3</LName>
</Name>
<Name>
<FName>Abc4</FName>
<LName>XYZ4</LName>
</Name>
</Names>
我试图在c#中预先更改节点名称,如果它们的出现不止一次并且除了第一个节点。第一个节点名称保持不变;
处理完XML后应该是这样的;
<Names>
<Name> // kepp first node name same
<FName>Abc</FName>
<LName>XYZ</LName>
</Name>
<ChildName> //changed
<FName>Abc2</FName>
<LName>XYZ2</LName>
</ChildName>
<ChildName> //changed
<FName>Abc3</FName>
<LName>XYZ3</LName>
</ChildName>
<ChildName> // changed
<FName>Abc4</FName>
<LName>XYZ4</LName>
</ChildName>
</Names>
Name的节点可以是1,如果是一次,保持不变,如果超过第一个并更改其他名称。
我想这个XML对象是IEnumerable<XElement>
类型;
//check if NAME node occurs multiple times, make other to child.
var nameCounts = element.Descendants().Where(x => x.Name.LocalName == "Name");
int number = nameCounts.Count();
if (number > 1) // if occurance more than one
{
foreach (var e in element.Descendants().Where(x => x.Name.LocalName == "Name").ToList())
{
//e.NodesAfterSelf();
// unable to understand what to do
}
}
更新:
但是我得到了我的问题的答案;我犯了一个小错误,实际上我的XML看起来像这样;
<ListOfNames>
<Names>
<Name> // two occurrence, 2nd will change to CHILD NAME
<FName>Abc</FName>
<LName>XYZ</LName>
</Name>
<Name>
<FName>Abc2</FName>
<LName>XYZ2</LName>
</Name>
</Names>
<Names> // three occurrence, 2nd and 3rd will change to CHILDNAME
<Name>
<FName>Abc</FName>
<LName>XYZ</LName>
</Name>
<Name>
<FName>Abc2</FName>
<LName>XYZ2</LName>
</Name>
<Name>
<FName>Abc2</FName>
<LName>XYZ2</LName>
</Name>
</Names>
<Names> // only one occurrence, nothing change
<Name>
<FName>Abc</FName>
<LName>XYZ</LName>
</Name>
</Names>
</ListOfNames>
答案 0 :(得分:3)
它比你现在制作它简单。您需要做的就是跳过第一个Name
元素,并更改其余元素的名称。要处理多个Names
元素,只需查找具有doc.Descendants("Names")
的每个元素,然后处理该容器中的元素。
以下是完全相同的代码:
using System;
using System.Linq;
using System.Xml.Linq;
public class Test
{
public static void Main(string[] args)
{
var doc = XDocument.Load("test.xml");
// Handle each Names element separately
foreach (var container in doc.Descendants("Names"))
{
// Within a names element, find all the Name elements,
// and materialize the query. (That may not be necessary; see later.)
var names = container.Elements("Name").ToList();
// Skip the first name, but modify each of the rest.
foreach (var element in names.Skip(1))
{
element.Name = "ChildName";
}
}
Console.WriteLine(doc);
}
}
ToList()
调用可能没有必要。对于在迭代查询时对文档所做的更改是否有问题,LINQ to XML并不是非常清楚(对我而言)。我当然看到我希望不出现问题的情况,但确实会引起问题 - 反之亦然。如果您知道您的文档足够小以至于实现结果实际上不会导致问题,我通常会这样做以避免进一步调查。