LINQ to XML:什么是上下移动节点的最有效方法
我需要在某些节点之前和之后移动兄弟节点。 这是我正在使用的代码
Overview Testing Performance Braking
我想在概述上方的测试中移动选项卡。 我如何使用linq to XML来解决这个问题?
对不起,这是VB.NET和XML Literals,但它可以在C#中完成旧学校。 这里的想法是使用Reverse
扩展方法:
Sub Main() Dim tab = Overview Testing Performance Braking Console.WriteLine(SwapElements("Testing", "Performance", tab).ToString) Console.ReadLine() End Sub Function SwapElements(ByVal firstElement As String, ByVal secondElement As String, ByVal tab As XElement) As XElement Dim swapped = tab.Elements.Where(Function(e) e.Value = firstElement Or e.Value = secondElement).Reverse Dim middle = tab.Elements.SelectMany(Function(e) e.ElementsAfterSelf.Where(Function(f) e.Value = firstElement).TakeWhile(Function(g) g.Value <> secondElement)) swapped.ElementAt(0).AddAfterSelf(middle) Return <<%= tab.Name %>> <%= tab.Elements.Select(Function(e) e.ElementsBeforeSelf.Where(Function(f) e.Value = firstElement)) %> <%= swapped %> <%= tab.Elements.Select(Function(e) e.ElementsAfterSelf.Where(Function(f) e.Value = secondElement)) %> > End Function
您可以通过移除元素移动它们,然后将它们重新插入所需位置:
var doc = XDocument.Parse(@"... "); var tab = doc.Root.Elements().ElementAt(1); tab.Remove(); doc.Root.AddFirst(tab);
或者,您可以按所需顺序从现有元素创建新文档:
var doc = XDocument.Parse(@"... "); var tabs = doc.Root.Elements(); var result = new XDocument( new XElement("tabs", tabs.ElementAt(1), tabs.ElementAt(0), tabs.ElementAt(2)));
我没有测试过,但这可能有效:
void Swap(XElement a, XElement b) { var c = new XElement("dummy"); a.ReplaceWith(c); b.ReplaceWith(a); c.ReplaceWith(b); }
您可以使用以下内容:
var tests = from node in doc.Descendants("name") where node.Value == "Testing" select node; var test = tests.Single(); var tab = test.Parent; var tabs = tab.Parent; tab.Remove(); tabs.AddFirst(tab);
不确定您的XML结构有多少是固定/已知的。
我知道这篇文章已经过时了,但我今天想出了同样的问题并最终以这种方式解决它:
private void SwapXNodes(bool up, int inUniqueID) { XElement currNode = DocumentManager.xMainDocument.XPathSelectElement("//*[@UniqueID='" + inUniqueID + "']"); // find if (up) { if (currNode.PreviousNode != null) { XElement xPrevious = new XElement((XElement)currNode.PreviousNode); // copy of previous node currNode.PreviousNode.ReplaceWith(currNode); // previous node equal to me currNode.ReplaceWith(xPrevious); // Now I should be equal to previous node } } else { if (currNode.NextNode != null) { XElement xNext = new XElement((XElement)currNode.NextNode); // copy of Next node currNode.NextNode.ReplaceWith(currNode); // Next node equal to me currNode.ReplaceWith(xNext); // Now I should be equal to Next node copy } } }