简体   繁体   English

如何将特定的XElement移至C#中的上一个节点?

[英]How do I move specific XElements to the previous node in C#?

Following is my XML: 以下是我的XML:

<navMap>
    <navPoint><content src="Text/01_Cover.xhtml"/></navPoint>
    <navPoint><content src="Text/02_Titlepage.xhtml#Titlepage"/></navPoint>
    <navPoint><content src="Text/03_Copyright.xhtml#Copyright"/></navPoint>
    <navPoint><content src="Text/04_Contents.xhtml#Contents"/></navPoint>
    <navPoint><content src="Text/05_Part01.xhtml#Part01"/></navPoint>
    <navPoint>
        <content src="Text/06_Part02.xhtml#Part02"/>
        <navPoint><content src="Text/06_Part02.xhtml#h3_2-1"/></navPoint>
        <navPoint>
            <content src="Text/08_Chapter01.xhtml#Chapter01"/>
            <navPoint><content src="Text/08_Chapter01.xhtml#h3_4-1"/></navPoint>
        </navPoint>
    </navPoint>
    <navPoint>
        <content src="Text/07_Part03.xhtml#Part03"/>
        <navPoint><content src="Text/07_Part03.xhtml#h3_3-1"/></navPoint>
    </navPoint>
    <navPoint><content src="Text/09_Chapter02.xhtml#Chapter02"/></navPoint>
    <navPoint><content src="Text/10_Chapter03.xhtml#Chapter03"/></navPoint>
    <navPoint><content src="Text/11_Chapter04.xhtml#Chapter04"/></navPoint>
    <navPoint><content src="Text/12_Chapter05.xhtml#Chapter05"/></navPoint>
</navMap>

In this XML, all the src attributes containing h3 is a child of it's respective parent and the rest are all separate elements. 在此XML中,所有包含h3src属性都是其各自父级的子级,其余均为单独的元素。

Similarly, I want to move all the Chapters to its respective part elements, like: 同样,我想将所有章节移至其各自的组成部分,例如:

<navMap>
    <navPoint><content src="Text/01_Cover.xhtml"/></navPoint>
    <navPoint><content src="Text/02_Titlepage.xhtml#Titlepage"/></navPoint>
    <navPoint><content src="Text/03_Copyright.xhtml#Copyright"/></navPoint>
    <navPoint><content src="Text/04_Contents.xhtml#Contents"/></navPoint>
    <navPoint><content src="Text/05_Part01.xhtml#Part01"/></navPoint>
    <navPoint>
        <content src="Text/06_Part02.xhtml#Part02"/>
        <navPoint><content src="Text/06_Part02.xhtml#h3_2-1"/></navPoint>
        <navPoint>
            <content src="Text/08_Chapter01.xhtml#Chapter01"/>
            <navPoint><content src="Text/08_Chapter01.xhtml#h3_4-1"/></navPoint>
        </navPoint>
    </navPoint>
    <navPoint>
        <content src="Text/07_Part03.xhtml#Part03"/>
        <navPoint><content src="Text/07_Part03.xhtml#h3_3-1"/></navPoint>
        <navPoint><content src="Text/09_Chapter02.xhtml#Chapter02"/></navPoint>
        <navPoint><content src="Text/10_Chapter03.xhtml#Chapter03"/></navPoint>
        <navPoint><content src="Text/11_Chapter04.xhtml#Chapter04"/></navPoint>
        <navPoint><content src="Text/12_Chapter05.xhtml#Chapter05"/></navPoint>
    </navPoint>
</navMap>

I have given indents to explain my need. 我已经缩进来解释我的需要。 I thought of something like: 我想到了类似的东西:

foreach (var element in xDoc.Root.Element("navMap").Elements())
{
    if (element.Element("content").Attribute("src").Value.Contains("_Chapter"))
    {
        var previousNode = element.PreviousNode;
        if (previousNode.Contains == "Part")
        {
            //Shift element to Part
        }
    }
}

The thing is that this will work for the very next Chapter only. 问题是,这会为第二天上班Chapter而已。 As you can see in the XML, there are multiple Chapters , so I want to move every single Chapter below Part to Part . 如您在XML中所见,有多个Chapters ,因此我想将Part之下的每个Chapter都移到Part If you notice, then Part02 has only one Chapter because there is a new Part03 after it so Part03 is a new parent element now. 如果您注意到了,那么Part02只有一个章节,因为它Part03有一个新的Part03 ,所以Part03现在是一个新的父元素。 All the elements containing Chapter will be a child of Part03 from here on and as soon as an element comes that does not contain Chapter, it will be a new parent element again. Part03 ,包含Chapter的所有元素将成为Part03的子元素,一旦不包含Chapter的元素出现,它将再次成为新的父元素。

While the question still isn't very clear to me, I think this does what you want: 尽管问题对我来说仍然不是清楚,但我认为这可以满足您的要求:

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        var document = XDocument.Load("input.xml");
        var points = document.Descendants("navPoint").ToList();

        XElement currentPart = null;
        foreach (var point in points)
        {
            var src = point.Element("content").Attribute("src").Value;
            if (src.Contains("#Part"))
            {
                currentPart = point;
            }
            else if (src.Contains("#Chapter"))
            {
                if (point.Parent != currentPart)
                {
                    point.Remove();
                    currentPart.Add(point);
                }
            }
        }
        document.Save("output.xml");
    }
}

This assumes that: 这假定:

  • Every navPoint element has a content element with a src attribute 每个navPoint元素都有一个带有src属性的content元素
  • There's always a part element before the first chapter element 第一章元素之前总有一个part元素
  • It's fine to just move chapter elements to the end within the current part element 只需将章节元素移动到当前part元素的末尾即可

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM