首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分隔XML文档,从重复元素中创建多个输出文件

分隔XML文档,从重复元素中创建多个输出文件
EN

Stack Overflow用户
提问于 2012-08-11 05:12:44
回答 2查看 8.9K关注 0票数 4

我需要获取一个XML文件,并从输入文件的重复节点创建多个输出xml文件。源文件"AnimalBatch.xml“如下所示:

<?xml version="1.0" encoding="utf-8" ?>

<Animals>

<Animal id="1001">

<Quantity>One</Quantity>

<Adjective>Red</Adjective>

<Name>Rooster</Name>

</Animal>

<Animal id="1002">

<Quantity>Two</Quantity>

<Adjective>Stubborn</Adjective>

<Name>Donkeys</Name>

</Animal>

<Animal id="1003">

<Quantity>Three</Quantity>

<Color>Blind</Color>

<Name>Mice</Name>

</Animal>

</Animals>

该程序需要拆分重复的“动物”并生成三个名为Animal_1001.xml、Animal_1002.xml和Animal_1003.xml的文件

每个输出文件应该只包含它们各自的元素(这将是根)。AnimalsBatch.xml的id属性将提供Animal_xxxx.xml文件名的序列号。id属性不需要在输出文件中。

Animal_1001.xml:

<?xml version="1.0" encoding="utf-8"?>

<Animal>

<Quantity>One</Quantity>

<Adjective>Red</Adjective>

<Name>Rooster</Name>

</Animal>

Animal_1002.xml

<?xml version="1.0" encoding="utf-8"?>

<Animal>

<Quantity>Two</Quantity>

<Adjective>Stubborn</Adjective>

<Name>Donkeys</Name>

</Animal>

Animal_1003.xml>

<?xml version="1.0" encoding="utf-8"?>

<Animal>

<Quantity>Three</Quantity>

<Adjective>Blind</Adjective>

<Name>Mice</Name>

</Animal>

我想用XmlDocument来实现这一点,因为它需要能够在.Net 2.0上运行。

我的程序是这样的:

代码语言:javascript
运行
复制
    static void Main(string[] args)
    {
        string strFileName;    
        string strSeq;                    

        XmlDocument doc = new XmlDocument(); 
        doc.Load("D:\\Rick\\Computer\\XML\\AnimalBatch.xml");

        XmlNodeList nl = doc.DocumentElement.SelectNodes("Animal");

        foreach (XmlNode n in nl)
        {
            strSeq = n.Attributes["id"].Value;

            XmlDocument outdoc = new XmlDocument();
            XmlNode rootnode = outdoc.CreateNode("element", "Animal", "");

            outdoc.AppendChild(rootnode); // Put the wrapper element into outdoc

            outdoc.ImportNode(n, true);   // place the node n into outdoc
            outdoc.AppendChild(n);        // This statement errors:
            // "The node to be inserted is from a different document context."

            strFileName = "Animal_" + strSeq + ".xml";

            outdoc.Save(Console.Out);
            Console.WriteLine();
        }
        Console.WriteLine("END OF PROGRAM:  Press <ENTER>");
        Console.ReadLine();
    }

我想我有两个问题。

( A)在将节点n上的ImportNode执行到outdoc之后,我调用outdoc.AppendChild(n),它抱怨道:“要插入的节点来自不同的文档上下文。”我不知道这是否是ForEach循环中引用节点n的作用域问题,或者我不知怎么没有正确地使用ImportNode()或AppendChild。ImportNode()上的第二个参数设置为true,因为我希望动物的子元素(3个字段任意命名数量、形容词和名称)在目标文件中结束。

( B)第二个问题是把动物元素弄到外面去。我得到了“但我需要”,这样我就可以在其中放置节点n。我想我的问题是我是怎么做的:outdoc.AppendChild(根节点);

为了显示xml,我做的是: outdoc.Save(Console.Out);我确实有将()保存到输出文件中的代码--只要我能够正确地组装出outdoc,它就能工作。

在:Split XML in Multiple XML files有一个类似的问题,但我还不明白解决方案代码。我认为我非常接近这个方法,并且会感谢你能提供的任何帮助。

我将使用XmlReader完成同样的任务,因为我需要能够处理大型输入文件,而且我知道XmlDocument会读取全部内容,并可能导致内存问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-11 07:08:14

这是一种简单的方法,看起来就是你想要的

代码语言:javascript
运行
复制
public void test_xml_split()
{
    XmlDocument doc = new XmlDocument();
    doc.Load("C:\\animals.xml");
    XmlDocument newXmlDoc = null;

    foreach (XmlNode animalNode in doc.SelectNodes("//Animals/Animal"))
    {
        newXmlDoc = new XmlDocument();
        var targetNode = newXmlDoc.ImportNode(animalNode, true);
        newXmlDoc.AppendChild(targetNode);
        newXmlDoc.Save(Console.Out);
        Console.WriteLine();
    }
}
票数 3
EN

Stack Overflow用户

发布于 2012-08-12 02:11:48

这种方法在不使用"var塔吉特节点“语句的情况下似乎有效。它从outdoc的“targetNode”元素在ForEach循环中创建一个名为targetNode的ForEach对象。我认为我的原始代码中的主要问题是:( A)我不正确地获得了nodelist nl。我不能“导入”节点n,我想是因为它是专门与doc关联的。它必须作为自己的节点创建。

先前提出的解决方案的问题是使用"var“关键字。我的程序必须假设2.0,而这是随v3.0而来的。我喜欢罗杰斯的解决方案,因为它很简洁。对我来说-我想做每一件事作为一个单独的陈述。

代码语言:javascript
运行
复制
    static void SplitXMLDocument() 
    {
        string strFileName;
        string strSeq;
        XmlDocument doc = new XmlDocument();             // The input file
        doc.Load("D:\\Rick\\Computer\\XML\\AnimalBatch.xml");
        XmlNodeList nl = doc.DocumentElement.SelectNodes("//Animals/Animal");

        foreach (XmlNode n in nl)
        {
            strSeq = n.Attributes["id"].Value;           // Animal nodes have an id attribute

            XmlDocument outdoc = new XmlDocument();      // Create the outdoc xml document
            XmlNode targetNode = outdoc.CreateElement("Animal"); // Create a separate node to hold the Animal element

            targetNode = outdoc.ImportNode(n, true);     // Bring over that Animal
            targetNode.Attributes.RemoveAll();           // Remove the id attribute in <Animal id="1001">

            outdoc.ImportNode(targetNode, true);         // place the node n into outdoc
            outdoc.AppendChild(targetNode);              // AppendChild to make it stick

            strFileName = "Animal_" + strSeq + ".xml";                
            outdoc.Save(Console.Out); Console.WriteLine();
            outdoc.Save("D:\\Rick\\Computer\\XML\\" + strFileName);
            Console.WriteLine();
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11912109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档