如何基于节点将XML文件拆分为多个XML文件

时间:2021-09-26 20:20:21

I have an XML file as follows

我有一个XML文件如下

<?xml version="1.0>
<EMR>
  <CustomTextBox>
    <Text>WNL</Text>
    <Type>TextBox</Type>
    <Width>500</Width>
    <id>txt1</id>
  </CustomTextBox>

  <CustomTextBox>
    <Text>WNL</Text>
    <Type>TextBox</Type>
    <Width>500</Width>
    <id>txt2</id>
  </CustomTextBox>

  <AllControlsCount>
    <Width>0</Width>
    <id>ControlsID</id>
  </AllControlsCount>
</EMR>

I want to split the xml file int o three. According to its nodes

我想将xml文件拆分为三个。根据它的节点

File 1:

<?xml version="1.0>
<CustomTextBox>
  <Text>WNL</Text>
  <Type>TextBox</Type>
  <Width>500</Width>
  <id>txt1</id>
</CustomTextBox>

File 2:

<?xml version="1.0>
<CustomTextBox>
  <Text>WNL</Text>
  <Type>TextBox</Type>
  <Width>500</Width>
  <id>txt2</id>
</CustomTextBox>

File 3:

<?xml version="1.0>
<AllControlsCount>
  <Width>0</Width>
  <id>ControlsID</id>
</AllControlsCount>

Also the nodes are dynamic, they may change. How can I split this xml file as multiple according to the nodes. If anybody knows please share.

节点也是动态的,它们可能会改变。如何根据节点将此xml文件拆分为多个。如果有人知道请分享。

3 个解决方案

#1


8  

Try LinqToXml:

var xDoc = XDocument.Parse(Resource1.XMLFile1); // loading source xml
var xmls = xDoc.Root.Elements().ToArray(); // split into elements

for(int i = 0;i< xmls.Length;i++)
{
    // write each element into different file
    using (var file = File.CreateText(string.Format("xml{0}.xml", i + 1)))
    {
        file.Write(xmls[i].ToString());
    }
}

It will take all elements defined inside the root element and write its content into separate files.

它将获取根元素内定义的所有元素,并将其内容写入单独的文件中。

#2


5  

With Linq to Xml its even simpler - you can use XElement.Save method to save any element to separate xml file:

使用Linq到Xml它更简单 - 您可以使用XElement.Save方法将任何元素保存到单独的xml文件中:

XDocument xdoc = XDocument.Load(path_to_xml);
int index = 0;
foreach (var element in xdoc.Root.Elements())
    element.Save(++index + ".xml");

Or one line

或者一行

XDocument.Load(path_to_xml).Root.Elements()
         .Select((e, i) => new { Element = e, File = ++i + ".xml" })
         .ToList().ForEach(x => x.Element.Save(x.File));

#3


1  

You can use XmlTextReader and XmlWriter classes to accomplish what you wish. But you need to know where you need to start creating new XML files. Looking at your example, you wish to split each node contained in the root node.

您可以使用XmlTextReader和XmlWriter类来完成您的任务。但是您需要知道开始创建新XML文件的位置。查看您的示例,您希望拆分根节点中包含的每个节点。

That means that once you start reading the XML file, you need to ensure that you are inside of the root node, then you need to follow how deep into the XML you are, so you can close the file when you reach next node in the root node.

这意味着一旦你开始阅读XML文件,你需要确保你在根节点内,然后你需要跟踪你的XML深度,这样你可以在到达下一个节点时关闭该文件。根节点。

See this for example - I read XML from file.xml and open XML writer. When I reach first node contained in the root node, I start writing the elements.

请参阅此示例 - 我从file.xml读取XML并打开XML编写器。当我到达根节点中包含的第一个节点时,我开始编写元素。

I remember the depth in variable "treeDepth", which represents the XML tree structure depth.

我记得变量“treeDepth”中的深度,它表示XML树结构深度。

Based on currently read node, I do an action. When I reach the End element that has tree depth 1, it means I am again in the root node, so I close the current XML file and open new one.

基于当前读取的节点,我做了一个动作。当我到达具有树深度1的End元素时,这意味着我再次位于根节点中,因此我关闭当前XML文件并打开新文件。

XmlTextReader reader = new XmlTextReader ("file.xml");

XmlWriter writer = XmlWriter.Create("first_file.xml")
writer.WriteStartDocument();

int treeDepth = 0;

while (reader.Read()) 
{
    switch (reader.NodeType) 
    {
        case XmlNodeType.Element:

            //
            // Move to parsing or skip the root node
            //

            if (treeDepth > 0)
                writer.WriteStartElement(reader.Name);

            treeDepth++;


            break;
  case XmlNodeType.Text:

            //
            // Write text here
            //

            writer.WriteElementString (reader.Value);

            break;
  case XmlNodeType.EndElement:

            //
            // Close the end element, open new file
            //

            if (treeDepth == 1)
            {
                writer.WriteEndDocument();
                writer = new XmlWriter("file2.xml");
                writer.WriteStartDocument();
            }

            treeDepth--;

            break;
    }
}

writer.WriteEndDocument();

Note that this code does NOT entirely solve your problem, but merely explains the logic needed to solve it completely.

请注意,此代码并不能完全解决您的问题,而只是解释了完全解决问题所需的逻辑。

For more help on XML readers and writers read following links:

有关XML阅读器和编写器的更多帮助,请阅读以下链接:

http://support.microsoft.com/kb/307548

http://www.dotnetperls.com/xmlwriter

#1


8  

Try LinqToXml:

var xDoc = XDocument.Parse(Resource1.XMLFile1); // loading source xml
var xmls = xDoc.Root.Elements().ToArray(); // split into elements

for(int i = 0;i< xmls.Length;i++)
{
    // write each element into different file
    using (var file = File.CreateText(string.Format("xml{0}.xml", i + 1)))
    {
        file.Write(xmls[i].ToString());
    }
}

It will take all elements defined inside the root element and write its content into separate files.

它将获取根元素内定义的所有元素,并将其内容写入单独的文件中。

#2


5  

With Linq to Xml its even simpler - you can use XElement.Save method to save any element to separate xml file:

使用Linq到Xml它更简单 - 您可以使用XElement.Save方法将任何元素保存到单独的xml文件中:

XDocument xdoc = XDocument.Load(path_to_xml);
int index = 0;
foreach (var element in xdoc.Root.Elements())
    element.Save(++index + ".xml");

Or one line

或者一行

XDocument.Load(path_to_xml).Root.Elements()
         .Select((e, i) => new { Element = e, File = ++i + ".xml" })
         .ToList().ForEach(x => x.Element.Save(x.File));

#3


1  

You can use XmlTextReader and XmlWriter classes to accomplish what you wish. But you need to know where you need to start creating new XML files. Looking at your example, you wish to split each node contained in the root node.

您可以使用XmlTextReader和XmlWriter类来完成您的任务。但是您需要知道开始创建新XML文件的位置。查看您的示例,您希望拆分根节点中包含的每个节点。

That means that once you start reading the XML file, you need to ensure that you are inside of the root node, then you need to follow how deep into the XML you are, so you can close the file when you reach next node in the root node.

这意味着一旦你开始阅读XML文件,你需要确保你在根节点内,然后你需要跟踪你的XML深度,这样你可以在到达下一个节点时关闭该文件。根节点。

See this for example - I read XML from file.xml and open XML writer. When I reach first node contained in the root node, I start writing the elements.

请参阅此示例 - 我从file.xml读取XML并打开XML编写器。当我到达根节点中包含的第一个节点时,我开始编写元素。

I remember the depth in variable "treeDepth", which represents the XML tree structure depth.

我记得变量“treeDepth”中的深度,它表示XML树结构深度。

Based on currently read node, I do an action. When I reach the End element that has tree depth 1, it means I am again in the root node, so I close the current XML file and open new one.

基于当前读取的节点,我做了一个动作。当我到达具有树深度1的End元素时,这意味着我再次位于根节点中,因此我关闭当前XML文件并打开新文件。

XmlTextReader reader = new XmlTextReader ("file.xml");

XmlWriter writer = XmlWriter.Create("first_file.xml")
writer.WriteStartDocument();

int treeDepth = 0;

while (reader.Read()) 
{
    switch (reader.NodeType) 
    {
        case XmlNodeType.Element:

            //
            // Move to parsing or skip the root node
            //

            if (treeDepth > 0)
                writer.WriteStartElement(reader.Name);

            treeDepth++;


            break;
  case XmlNodeType.Text:

            //
            // Write text here
            //

            writer.WriteElementString (reader.Value);

            break;
  case XmlNodeType.EndElement:

            //
            // Close the end element, open new file
            //

            if (treeDepth == 1)
            {
                writer.WriteEndDocument();
                writer = new XmlWriter("file2.xml");
                writer.WriteStartDocument();
            }

            treeDepth--;

            break;
    }
}

writer.WriteEndDocument();

Note that this code does NOT entirely solve your problem, but merely explains the logic needed to solve it completely.

请注意,此代码并不能完全解决您的问题,而只是解释了完全解决问题所需的逻辑。

For more help on XML readers and writers read following links:

有关XML阅读器和编写器的更多帮助,请阅读以下链接:

http://support.microsoft.com/kb/307548

http://www.dotnetperls.com/xmlwriter