在 C# 中拆分 XML 文件并保留外部节点
Split XML file in C# and keep the outer nodes
我有一个 XML 文件,如下所示:
<root>
<elements>
<element>
<value1>a</value1>
<value2>b</value2>
</element>
<element>
<value1>c</value1>
<value2>d</value2>
</element>
<element>
<value1>e</value1>
<value2>f</value2>
</element>
<element>
<value1>g</value1>
<value2>h</value2>
</element>
</elements>
<return>0</return></root>
我想把它分成 x 个文件,如下所示:
例如
<root>
<elements>
<element>
<value1>a</value1>
<value2>b</value2>
</element>
<element>
<value1>c</value1>
<value2>d</value2>
</element>
</elements>
<return>0</return></root>
我使用的代码真的很丑,一点也不通用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace XMLSplit2
{
class Program
{
static void Main(string[] args)
{
string filePath, file, outputFolder;
XDocument xml;
file = @"test.xml";
outputFolder = @"C:\test\out\";
filePath = @"C:\test\in\" + file;
string _Header = @"<root><elements>";
string _Footer = @"</elements><return>0</return></root>";
int _BatchSize = 2;
int i = 0;
int j = 0;
xml = XDocument.Load(filePath);
XElement element = xml.Root.Elements().ElementAt(0);
var xdoc = new XDocument(element);
StringBuilder sb = new StringBuilder();
string newXml = "";
sb.Append(_Header);
XElement last = xdoc.Root.Elements().Last();
foreach (XElement singleElement in xdoc.Root.Elements())
{
i++;
sb.Append(singleElement.ToString());
if (i % _BatchSize == 0 || singleElement.Equals(last))
{
j++;
sb.Append(_Footer);
newXml = sb.ToString();
System.IO.File.WriteAllText(outputFolder + j.ToString() + "_" + file, newXml);
sb.Clear();
sb.Append(_Header);
}
}
}
}
}
我想去掉变量_Header和_Footer。我该怎么做才能保留边框并用 x 个元素节点填充它?或者没有 xslt 是不可能的?
通常应避免使用字符串连接构建 XML 文件。使用Linq-to-XML
时就简单多了:
// use this namespace
using System.Xml.Linq;
// Create 'footer' and 'header' elements
XDocument xmlDoc = new XDocument();
XElement xElm = new XElement("root",
new XElement("elements"),
new XElement("return", 0)
);
xmlDoc.Add(xElm);
生产:
- <root>
<elements />
<return>0</return>
</root>
您现在可以轻松地从原始 XML 文件中添加您想要的任何节点:
// Load XML file
XDocument doc = XDocument.Load(@"C:\mypath\mydoc.xml");
// Take the first two <element>s and add them to the new XML being produced
foreach (XElement elm in doc.Descendants("element").Take(2))
{
xmlDoc.Root.Element("elements").Add(new XElement(elm));
}
获得所需的结果:
- <root>
- <elements>
- <element>
<value1>a</value1>
<value2>b</value2>
</element>
- <element>
<value1>c</value1>
<value2>d</value2>
</element>
</elements>
<return>0</return>
</root>
您可以使用以下解决方案来实现您的目标。
try
{
var xDoc = new XmlDocument();
string file = "input.xml";
int batchSize = 2;
if(File.Exists(file))
{
xDoc.Load(file);
var elements = xDoc.DocumentElement.SelectNodes("/root/elements/element");
if(elements!=null && elements.Count>batchSize)
{
var elementsToRetain = elements.OfType<XmlNode>().Take(batchSize);
var elementsNode = xDoc.DocumentElement.SelectSingleNode("/root/elements");
elementsNode.RemoveAll();
foreach(var ele in elementsToRetain)
{
elementsNode.AppendChild(ele);
}
}
xDoc.Save("output.xml");
}
}
catch (Exception e)
{
}
我有一个 XML 文件,如下所示:
<root>
<elements>
<element>
<value1>a</value1>
<value2>b</value2>
</element>
<element>
<value1>c</value1>
<value2>d</value2>
</element>
<element>
<value1>e</value1>
<value2>f</value2>
</element>
<element>
<value1>g</value1>
<value2>h</value2>
</element>
</elements>
<return>0</return></root>
我想把它分成 x 个文件,如下所示: 例如
<root>
<elements>
<element>
<value1>a</value1>
<value2>b</value2>
</element>
<element>
<value1>c</value1>
<value2>d</value2>
</element>
</elements>
<return>0</return></root>
我使用的代码真的很丑,一点也不通用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace XMLSplit2
{
class Program
{
static void Main(string[] args)
{
string filePath, file, outputFolder;
XDocument xml;
file = @"test.xml";
outputFolder = @"C:\test\out\";
filePath = @"C:\test\in\" + file;
string _Header = @"<root><elements>";
string _Footer = @"</elements><return>0</return></root>";
int _BatchSize = 2;
int i = 0;
int j = 0;
xml = XDocument.Load(filePath);
XElement element = xml.Root.Elements().ElementAt(0);
var xdoc = new XDocument(element);
StringBuilder sb = new StringBuilder();
string newXml = "";
sb.Append(_Header);
XElement last = xdoc.Root.Elements().Last();
foreach (XElement singleElement in xdoc.Root.Elements())
{
i++;
sb.Append(singleElement.ToString());
if (i % _BatchSize == 0 || singleElement.Equals(last))
{
j++;
sb.Append(_Footer);
newXml = sb.ToString();
System.IO.File.WriteAllText(outputFolder + j.ToString() + "_" + file, newXml);
sb.Clear();
sb.Append(_Header);
}
}
}
}
}
我想去掉变量_Header和_Footer。我该怎么做才能保留边框并用 x 个元素节点填充它?或者没有 xslt 是不可能的?
通常应避免使用字符串连接构建 XML 文件。使用Linq-to-XML
时就简单多了:
// use this namespace
using System.Xml.Linq;
// Create 'footer' and 'header' elements
XDocument xmlDoc = new XDocument();
XElement xElm = new XElement("root",
new XElement("elements"),
new XElement("return", 0)
);
xmlDoc.Add(xElm);
生产:
- <root>
<elements />
<return>0</return>
</root>
您现在可以轻松地从原始 XML 文件中添加您想要的任何节点:
// Load XML file
XDocument doc = XDocument.Load(@"C:\mypath\mydoc.xml");
// Take the first two <element>s and add them to the new XML being produced
foreach (XElement elm in doc.Descendants("element").Take(2))
{
xmlDoc.Root.Element("elements").Add(new XElement(elm));
}
获得所需的结果:
- <root>
- <elements>
- <element>
<value1>a</value1>
<value2>b</value2>
</element>
- <element>
<value1>c</value1>
<value2>d</value2>
</element>
</elements>
<return>0</return>
</root>
您可以使用以下解决方案来实现您的目标。
try
{
var xDoc = new XmlDocument();
string file = "input.xml";
int batchSize = 2;
if(File.Exists(file))
{
xDoc.Load(file);
var elements = xDoc.DocumentElement.SelectNodes("/root/elements/element");
if(elements!=null && elements.Count>batchSize)
{
var elementsToRetain = elements.OfType<XmlNode>().Take(batchSize);
var elementsNode = xDoc.DocumentElement.SelectSingleNode("/root/elements");
elementsNode.RemoveAll();
foreach(var ele in elementsToRetain)
{
elementsNode.AppendChild(ele);
}
}
xDoc.Save("output.xml");
}
}
catch (Exception e)
{
}