我需要获取一个 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>
但实际上,其中没有 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 对象。