C# XmlDocument重新排列XMLC节点#

C# XmlDocument重新排列XMLC节点#,c#,xml,xmldocument,xmlnode,C#,Xml,Xmldocument,Xmlnode,我有一个XML文档,它存储了关于系统用户的各种信息。就气候而言,我感兴趣的节点已经在下面列出了 因此,有一个用户有很多用户内容——我只以书籍为例 <?xml version="1.0" encoding="UTF-8"?> <user> <userProperties> <alias val="userAliasOne"/> <id val="3423423"/> </userProperties>

我有一个XML文档,它存储了关于系统用户的各种信息。就气候而言,我感兴趣的节点已经在下面列出了

因此,有一个用户有很多用户内容——我只以书籍为例

<?xml version="1.0" encoding="UTF-8"?>
<user>
  <userProperties>
    <alias val="userAliasOne"/>
    <id val="3423423"/>
  </userProperties>
  <userContent>
    <userBooks>
      <genre>
        <book>
          <title>Dummy Value</title>
        </book>
      </genre>
    </userBooks>
  </userContent>
</user>

虚拟值
我需要使用XmlDocument和XmlNode以某种方式重新构造XML,使其与下面的内容相匹配。(userBooks将成为根节点,但userBooks-/genre/book/title的所有内容将保留在userContent中)


虚拟值
我尝试选择单个节点并克隆它们,然后将克隆附加到父节点并删除不再需要的子节点。它变得又长又复杂,我无法让它工作。一定有一个我不知道的更优雅的解决方案

谢谢你的帮助


谢谢。

以下是添加新根元素的示例:

using System;
using System.Xml;

class Test
{
    static void Main()
    {
        XmlDocument doc = new XmlDocument();
        doc.Load("test.xml");
        var originalRoot = doc.DocumentElement;
        doc.RemoveChild(originalRoot);
        var newRoot = doc.CreateElement("userBooks");
        doc.AppendChild(newRoot);
        newRoot.AppendChild(originalRoot);
        doc.Save(Console.Out);
    }
}

尝试使用相同的方法“删除”原始中的
userBooks
元素-从其父元素中删除该元素,然后将所有子节点(属于
userBooks
)添加为
userBooks

原始父元素的新子节点以下是添加新根元素的示例:

using System;
using System.Xml;

class Test
{
    static void Main()
    {
        XmlDocument doc = new XmlDocument();
        doc.Load("test.xml");
        var originalRoot = doc.DocumentElement;
        doc.RemoveChild(originalRoot);
        var newRoot = doc.CreateElement("userBooks");
        doc.AppendChild(newRoot);
        newRoot.AppendChild(originalRoot);
        doc.Save(Console.Out);
    }
}
尝试使用相同的方法“删除”原始中的
userBooks
元素-从其父元素中删除该元素,然后使用XML Linq将所有子节点(属于
userBooks
)添加为
userBooks

原始父元素的新子节点

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load(FILENAME);
            List<XElement> userBooks = doc.Descendants("userBooks").ToList();

            foreach(XElement userBook in userBooks)
            {
                userBook.ReplaceWith(userBook.Element("genre"));
            }
        }
    }
}
​
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
List userBooks=doc.substands(“userBooks”).ToList();
foreach(用户手册中的XElement用户手册)
{
替换为(userBook.Element(“流派”);
}
}
}
}
​
使用XML Linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load(FILENAME);
            List<XElement> userBooks = doc.Descendants("userBooks").ToList();

            foreach(XElement userBook in userBooks)
            {
                userBook.ReplaceWith(userBook.Element("genre"));
            }
        }
    }
}
​
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
List userBooks=doc.substands(“userBooks”).ToList();
foreach(用户手册中的XElement用户手册)
{
替换为(userBook.Element(“流派”);
}
}
}
}
​

您是否有可能使用LINQ转换为XML而不是
XmlDocument
?这是一个简单得多的API。@JonSkeet这里的主要问题是,我继承的其余代码非常旧,并且使用XmlDocument。我已经看到,在发布本文之前搜索时使用LINQtoSQL是多么简单。这让我今天感到困扰了一段时间。这里看起来有两个变化:1)添加
userbook
的新根元素以包含
user
;2) 将
类型
元素移动到仅
用户内容
。这两个你都能用吗?将它们作为单独的问题处理。您考虑过使用XSL吗?它非常擅长改变XML的模式,并且在.NET中得到了很好的支持。当然,如果你能在你的解决方案中找到答案,那么如果你有两个问题,你应该用两个问题来提问——或者先选择一个问题来解决,看看这个问题的答案是否对另一个问题有帮助。(正如Matt所说,XSL在这里很可能是一个很好的选择。我通常觉得它很棘手,但XmlDocument API也很棘手……)有没有可能使用LINQ to XML而不是
XmlDocument
?这是一个简单得多的API。@JonSkeet这里的主要问题是,我继承的其余代码非常旧,并且使用XmlDocument。我已经看到,在发布本文之前搜索时使用LINQtoSQL是多么简单。这让我今天感到困扰了一段时间。这里看起来有两个变化:1)添加
userbook
的新根元素以包含
user
;2) 将
类型
元素移动到仅
用户内容
。这两个你都能用吗?将它们作为单独的问题处理。您考虑过使用XSL吗?它非常擅长改变XML的模式,并且在.NET中得到了很好的支持。当然,如果你能在你的解决方案中找到答案,那么如果你有两个问题,你应该用两个问题来提问——或者先选择一个问题来解决,看看这个问题的答案是否对另一个问题有帮助。(正如Matt所说,XSL在这里很可能是一个很好的选择。我通常觉得它很棘手,但是XMLDocumentAPI也很棘手……)