问题
I have the following XML structure:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root xmlns:xsi="My Program">
<NotRoot Text="Hello">
<SomeOption Text="Option 1" Centered="False">
<SomeOption Text="Option 1.1" Centered="False">
<SomeOption Text="Option 1.1.1" Centered="false">
<SomeOption Text="A" Centered="false">
<SpecialName Text="Blah blah" Centered="false">
<Number>1</Number>
</SpecialName>
</SomeOption>
<SomeOption Text="B" Centered="false">
<SpecialName Text="Hi" Centered="true">
<SomeStrangeName>42</SomeStrangeName>
</SpecialName>
</SomeOption>
<SomeOption Text="C" Centered="false">
<SpecialName Text="Some text here" Centered="false">
<Stuff>
<Thing1>10</Thing1>
<Thing2>20</Thing2>
<Thing3>30</Thing3>
</Stuff>
</SpecialName>
</SomeOption>
<SomeOption Text="D" Centered="false">
<SpecialName Text="Bye" Centered="false">
<Things>
<Random1>9846516981</Random1>
<Random2>8784749874</Random2>
</Things>
</SpecialName>
</SomeOption>
</SomeOption>
</SomeOption>
</SomeOption>
</NotRoot>
</Root>
I would like to move the element "C" up one position so that the output looks like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root xmlns:xsi="My Program">
<NotRoot Text="Hello">
<SomeOption Text="Option 1" Centered="False">
<SomeOption Text="Option 1.1" Centered="False">
<SomeOption Text="Option 1.1.1" Centered="false">
<SomeOption Text="A" Centered="false">
<SpecialName Text="Blah blah" Centered="false">
<Number>1</Number>
</SpecialName>
</SomeOption>
<SomeOption Text="C" Centered="false">
<SpecialName Text="Some text here" Centered="false">
<Stuff>
<Thing1>10</Thing1>
<Thing2>20</Thing2>
<Thing3>30</Thing3>
</Stuff>
</SpecialName>
</SomeOption>
<SomeOption Text="B" Centered="false">
<SpecialName Text="Hi" Centered="true">
<SomeStrangeName>42</SomeStrangeName>
</SpecialName>
</SomeOption>
<SomeOption Text="D" Centered="false">
<SpecialName Text="Bye" Centered="false">
<Things>
<Random1>9846516981</Random1>
<Random2>8784749874</Random2>
</Things>
</SpecialName>
</SomeOption>
</SomeOption>
</SomeOption>
</SomeOption>
</NotRoot>
</Root>
My "Move Element Up" button can recognize the element to move and the element above it with this code:
public void MoveElementUp(XElement xeElementToMove)
{
XElement xeElementToMoveInXML = xmlRoot.Descendants().Single(xe => xe == xeElementToMove);
XElement xePrevious = XElement.Parse(xeElementToMoveInXML.PreviousNode.ToString());
// Do something here to put xeElementToMoveInXML before xePrevious
SaveXML();
}
I think I may be going about it the wrong way though. Perhaps I need to parse it all as regular text, then move it somehow, then convert it back to XML elements?
回答1:
Simple:
- Find its current "previous" element
- Remove it from the tree
- Insert it before the element you found
Something like this:
static void MoveElementUp(XElement element)
{
// Walk backwards until we find an element - ignore text nodes
XNode previousNode = element.PreviousNode;
while (previousNode != null && !(previousNode is XElement))
{
previousNode = previousNode.PreviousNode;
}
if (previousNode == null)
{
throw new ArgumentException("Nowhere to move element to!");
}
element.Remove();
previousNode.AddBeforeSelf(element);
}
来源:https://stackoverflow.com/questions/3087891/how-can-i-move-an-xml-element-above-the-previous-element-using-linq-to-xml