我需要在某些节点之前和之后移动兄弟节点。这是我正在使用的代码
<tabs>
<tab>
<name>Overview</name>
</tab>
<tab>
<name>Testing</name>
</tab>
<tab>
<name>Performance</name>
</tab>
<tab>
<name>Braking</name>
</tab>
</tabs>
我想在概述上方的测试中移动选项卡。我如何使用linq to XML进行此操作?
答案 0 :(得分:3)
您可以移除元素,然后将它们重新插入所需位置:
var doc = XDocument.Parse(@"<tabs>...</tabs>");
var tab = doc.Root.Elements().ElementAt(1);
tab.Remove();
doc.Root.AddFirst(tab);
或者,您可以按所需顺序从现有元素创建新文档:
var doc = XDocument.Parse(@"<tabs>...</tabs>");
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);
}
答案 1 :(得分:2)
抱歉,这是VB.NET和XML Literals,但它可以在C#中完成旧学校。这里的想法是使用Reverse
扩展方法:
Sub Main()
Dim tab = <tabs>
<tab>
<name>Overview</name>
</tab>
<tab>
<name>Testing</name>
</tab>
<tab>
<name>Performance</name>
</tab>
<tab>
<name>Braking</name>
</tab>
</tabs>
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
答案 2 :(得分:1)
您可以使用以下内容:
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结构有多少是固定/已知的。
答案 3 :(得分:1)
我知道这篇文章已经过时了,但我今天提出了同样的问题并最终解决了这个问题:
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
}
}
}