Ошибка XML: существует несколько корневых элементов
Я получаю XML от веб-службы. Вот как выглядит XML:
<parent>
<child>
Text
</child>
</parent>
<parent>
<child>
<grandchild>
Text
</grandchild>
<grandchild>
Text
</grandchild>
</child>
<child>
Text
</child>
</parent>
etc.
И вот мой код С#:
StringBuilder output = new StringBuilder();
// Create an XmlReader
using (XmlReader reader = XmlReader.Create(new StringReader([email protected])))
{
XmlWriterSettings ws = new XmlWriterSettings();
//ws.Indent = true;
using (XmlWriter writer = XmlWriter.Create(output, ws))
{
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(reader.Name);
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
writer.WriteComment(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
}
}
}
}
Я считаю, что ошибка возникает во втором родительском элементе. Как я могу избежать этой ошибки? Любая помощь приветствуется.
Ответы
Ответ 1
Вам необходимо заключить ваши элементы <parent>
в окружающий элемент, поскольку XML-документы могут иметь только один корневой узел:
<parents> <!-- I've added this tag -->
<parent>
<child>
Text
</child>
</parent>
<parent>
<child>
<grandchild>
Text
</grandchild>
<grandchild>
Text
</grandchild>
</child>
<child>
Text
</child>
</parent>
</parents> <!-- I've added this tag -->
Поскольку вы получаете эту разметку из другого места, а не генерируете ее самостоятельно, вам, возможно, придется сделать это самостоятельно, обработав ответ как строку и обернув его соответствующими тегами, прежде чем пытаться проанализировать его как XML.
Итак, у вас есть несколько вариантов:
- Попросите поставщика веб-службы вернуть вам фактический XML файл с одним корневым узлом
- Предварительно обработайте XML, как я уже говорил выше, чтобы добавить корневой узел
- Предварительно обработайте XML, чтобы разделить его на несколько частей (то есть по одному на каждый узел
<parent>
) и обработать каждый как отдельный документ XML.
Ответ 2
Вы можете сделать это, не изменяя поток XML: скажите XmlReader, чтобы он не был настолько придирчивым.
Установка XmlReaderSettings.ConformanceLevel
в ConformanceLevel.Fragment
позволит синтаксическому анализатору игнорировать тот факт, что нет корня node.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create(tr,settings))
{
...
}
Теперь вы можете разобрать что-то вроде этого (это поток XML реального времени, где невозможно обернуть с помощью node).
<event>
<timeStamp>1354902435238</timeStamp>
<eventId>7073822</eventId>
</event>
<data>
<time>1354902435341</time>
<payload type='80'>7d1300786a0000000bf9458b0518000000000000000000000000000000000c0c030306001b</payload>
</data>
<data>
<time>1354902435345</time>
<payload type='80'>fd1260780912ff3028fea5ffc0387d640fa550f40fbdf7afffe001fff8200fff00f0bf0e000042201421100224ff40312300111400004f000000e0c0fbd1e0000f10e0fccc2ff0000f0fe00f00f0eed00f11e10d010021420401</payload>
</data>
<data>
<time>1354902435347</time>
<payload type='80'>fd126078ad11fc4015fefdf5b042ff1010223500000000000000003007ff00f20e0f01000e0000dc0f01000f000000000000004f000000f104ff001000210f000013010000c6da000000680ffa807800200000000d00c0f0</payload>
</data>
Ответ 3
Оберните xml в другой элемент
<wrapper>
<parent>
<child>
Text
</child>
</parent>
<parent>
<child>
<grandchild>
Text
</grandchild>
<grandchild>
Text
</grandchild>
</child>
<child>
Text
</child>
</parent>
</wrapper>
Ответ 4
Если вы отвечаете (или имеете какой-либо контроль над веб-службой), попросите их добавить уникальный корневой элемент!
Если вы вообще ничего не можете изменить, вы можете сделать немного регулярного выражения или расщепления строк для каждого анализа и передать каждый элемент в свой XML-ридер.
В качестве альтернативы вы можете вручную добавить ненужный корневой элемент, предварительно добавив открывающий тег и суффикс закрывающего тега.