【发布时间】:2012-08-27 05:57:42
【问题描述】:
我需要获取一个 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>
@ 987654337@</Animals>
但实际上,其中没有 CR/LF 字符。实际的文本流如下所示:
<?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”进行拆分,生成3个文件,分别命名为:Animal_1001.xml、Animal_1002.xml、Animal_1003.xml
我之前使用 XmlDocument 对此有过疑问,该问题已得到解答。
参见:[使用 XmlDocument 将 XML 文件拆分为多个 xml][1]
这个问题是关于如何使用 XmlReader 来抓取元素并从中创建 XmlDocument 元素。
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>
这是有效的代码 - 但仅当输入文件中有换行符时:
static void SplitXMLReader()
{
string strFileName;
string strSeq;
XmlReader doc = XmlReader.Create("C:\\AnimalBatch.xml");
while (doc.Read())
{
if (doc.Name=="Animal")
{
strSeq = doc.GetAttribute("id");
XmlDocument outdoc = new XmlDocument();
XmlDeclaration xmlDeclaration = outdoc.CreateXmlDeclaration("1.0", "utf-8", null);
XmlElement rootNode = outdoc.CreateElement(doc.Name);
rootNode.InnerXml = doc.ReadInnerXml();
outdoc.InsertBefore(xmlDeclaration, outdoc.DocumentElement);
outdoc.AppendChild(rootNode);
strFileName = "Animal_" + strSeq + ".xml";
outdoc.Save("C:\\" + strFileName);
}
}
}
当此程序在每个元素后都有回车符的“AnimalBatch.xml”副本上运行时 - 它可以工作,并根据需要创建 Animal_xxxx.xml 文件。当 AnimalBatch.xml 看起来像未格式化的文本流时 - 它获取第一个 Animal - 并且可以获得它的 ID 1001 并写入输出文件 ok。它能够读取后续的 Animal 元素但不能获取“id”属性 - 并最终写入名为“Animal_.xml”的输出文件 - 因为它试图从属性中读取的 strSeq 变量显然是 null 或空白。最后,第二个文件只包含这个:
<?xml version="1.0" encoding="utf-8"?><Animal />
这让我相信 XmlReader,至少在 doc.Read() 方法的范围内,(doc.Name=="Animal") 语句或后来的“strSeq = doc.GetAttribute("id" );
" - 如果<Animal id="1002"> 标记后有 CR/LF,则工作方式不同。
我想我真正的问题是 - 什么时候 doc.GetAttribute("id");文档中的光标在哪里?为什么它不能得到“1001”之后的那些 - 这确实有效?
John 说 XML 不关心格式 - 我也一直这么认为 - 但这令人困惑。另外 - 对于我的应用程序,我可以获得 XML 的唯一方法是未格式化,因为我通过 SSIS 退出 SQL,它是文本流,而不是 XML 对象。
【问题讨论】:
-
仅供参考,请勿使用
new XmlTextReader。请改用XmlReader.Create。 -
约翰 - 我得给你起立鼓掌。您观察到使用 XmlReader 而不是 XmlTextReader 是解决方案。文本阅读器的问题显然与它无法识别随后的“动物”元素有关(它会得到第一个 - 但当我试图获取属性“ID”时 - 它只找到第一个 -好吧 - 我手上一团糟。我将发布现在有效的代码。
-
John - 我发现我的输入文件没有 CR/LF 的“格式”,如我的示例中所示。这是否意味着我必须使用 xmlTextReader?我已经使用它取得了一定程度的成功(即我可以获得外部 xml - 只是无法提取 ID 属性)。也许我需要在一个单独的问题中指定这一点。
-
格式化与 XML 无关。
标签: c# xml split large-files xmltextreader