Мне нужно взять 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>
Программа должна разделить повторяющееся «Животное» и создать 3 файла с именами: Animal_1001.xml, Animal_1002.xml и Animal_1003.xml.
У меня был предыдущий вопрос по этому поводу, используя XmlDocument, на который уже был дан ответ.
См .: [Разделение XML-файла на несколько XML-файлов с помощью XmlDocument] [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 - и может получить его идентификатор 1001 и записать выходной файл нормально. Он может читать последующие элементы 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» - что работает?
Джон сказал, что XML не заботится о форматировании - и я всегда так думал, - но это сбивает с толку. Кроме того, для моего приложения единственный способ получить XML - неформатированный, поскольку я выхожу из SQL через SSIS, и это текстовый поток, а не объект XML.
new XmlTextReader
. Вместо этого используйтеXmlReader.Create
. - person John Saunders   schedule 27.08.2012