我试图只按ID在相同名称标签之间对xml标签进行排序,所以我想在其子元素中进行相同的处理。现在,我只能对根的第一级进行排序。有什么想法可以使它更有效吗?
谢谢您的建议。
之前的示例:
<AFDatabase>
<Element1><id>1</id></Element1>
<Element1><id>10</id></Element1>
<Element1><id>5</id></Element1>
<Element1><id>4</id>
<ElementInside><id>3</id><ElementInside>
<ElementInside><id>2</id><ElementInside>
<ElementInside><id>1</id><ElementInside>
<ElementInside><id>0</id><ElementInside>
<ElementInside4><id>3</id><ElementInside4>
<ElementInside4><id>2</id><ElementInside4>
<ElementInside4><id>1</id><ElementInside4>
<ElementInside2><id>3</id><ElementInside2>
<ElementInside2><id>2</id><ElementInside2>
<ElementInside2><id>1</id><ElementInside2>
</Element1>
//// AFTER ///
<AFDatabase>
<Element1><id>1</id></Element1>
<Element1><id>4</id>
<ElementInside><id>0</id><ElementInside>
<ElementInside><id>1</id><ElementInside>
<ElementInside><id>2</id><ElementInside>
<ElementInside><id>3</id><ElementInside>
<ElementInside4><id>1</id><ElementInside4>
<ElementInside4><id>2</id><ElementInside4>
<ElementInside4><id>3</id><ElementInside4>
<ElementInside2><id>1</id><ElementInside2>
<ElementInside2><id>2</id><ElementInside2>
<ElementInside2><id>3</id><ElementInside2>
</Element1>
<Element1><id>5</id></Element1>
<Element1><id>10</id></Element1>
</AFDatabase>
代码
private static XElement xmlSorting(XElement root)
{
var xmlStruct = sortRootBYID(root);
return new XElement(root.Name,
root.Attributes(), new XElement("AFDatabase",
from child in root.Nodes()
where child.NodeType != XmlNodeType.Element
select child,
from child in xmlStruct.Elements()
select child));
}
private static XElement sortRootBYID(XElement root)
{
var ElementNames = getElementNames(root);
var xmlStruct = new XElement("x");
xmlStruct.RemoveAll();
foreach (var elementName in ElementNames)
{
var orderedTags = root.Elements("AFDatabase").Elements(elementName)
.OrderBy(xtab => (string)xtab.Element("id"))
.ToArray();
foreach (XElement tag in orderedTags)
xmlStruct.Add(tag);
}
return xmlStruct;
}
private static HashSet<string> getElementNames (XElement root)
{
HashSet<string> ElementNames = new HashSet<string>();
foreach (var element in root.Elements().Elements())
{
//Console.WriteLine();
if (element.Name != null)
{
ElementNames.Add(element.Name.ToString());
}
}
return ElementNames;
}
答案 0 :(得分:0)
实现此目的的一种方法如下。您需要先对“第一级”元素进行排序,然后再根据“元素名称”对内部元素进行分组,然后对其进行排序。
var xDoc = XDocument.Parse(xml);
var elementCollection = xDoc.Root.Elements("Element1")
.OrderBy(x=> int.Parse(x.Element("id").Value)).ToList();
foreach(var element in elementCollection.Where(x=>x.Descendants().Any(c=>c.Name.LocalName.StartsWith("ElementInside"))).ToArray())
{
var innerElements = element.Descendants()
.Where(x=>!x.Name.LocalName.Equals("id"))
.GroupBy(x=>x.Name.LocalName)
.Select(x=>x.ToList().OrderBy(c=>c.Element("id") == null ? "0" : c.Element("id").Value))
.SelectMany(x=>x).ToList();
innerElements.Insert(0,element.Element("id"));
element.ReplaceAll(innerElements);
}
var result = new XElement("AFDatabase", elementCollection);