Проблема с чтением XML-файла в набор данных C#.
Вопрос
Мне дали файл .xml, который мне нужно было прочитать в моем коде как набор данных (в качестве фона файл был создан путем создания DataSet
в С# и вызове dataSet.WriteXml(file, XmlWriteMode.IgnoreSchema)
, но это сделал кто-то другой).
Файл .xml имел следующую форму:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Foo>
<Bar>abcd</Bar>
<Foo>efg</Foo>
</Foo>
<Foo>
<Bar>hijk</Bar>
<Foo>lmn</Foo>
</Foo>
</NewDataSet>
Используя C# и .NET 2.0, я прочитал файл, используя приведенный ниже код:
DataSet ds = new DataSet();
ds.ReadXml(file);
Используя точку останова, после этого line ds.Tables[0]
выглядело так (с использованием тире вместо подчеркиваний, которые я не смог правильно отформатировать):
Bar Foo-Id Foo-Id-0
abcd 0 null
null 1 0
hijk 2 null
null 3 2
Я нашел обходной путь (я знаю, что их много) и смог успешно прочитать файл .xml, но мне хотелось бы понять, почему ds.ReadXml(file)
выполнено таким образом, поэтому я смогу избежать этой проблемы в будущем.Спасибо.
Решение
Кажется, это правильно для вашего вложенный Фу-теги:
<NewDataSet>
<Foo> <!-- Foo-Id: 0 -->
<Bar>abcd</Bar>
<Foo>efg</Foo> <!-- Foo-Id: 1, Parent-Id: 0 -->
</Foo>
<Foo> <!-- Foo-Id: 2 -->
<Bar>hijk</Bar>
<Foo>lmn</Foo> <!-- Foo-Id: 3, Parent-Id: 2 -->
</Foo>
</NewDataSet>
Таким образом, в вашем результате правильно получается 4 записи с родительским-дочерним ключом «Foo-Id-0».
Пытаться:
<NewDataSet>
<Rec> <!-- Rec-Id: 0 -->
<Bar>abcd</Bar>
<Foo>efg</Foo>
</Rec>
<Rec> <!-- Rec-Id: 1 -->
<Bar>hijk</Bar>
<Foo>lmn</Foo>
</Rec>
</NewDataSet>
Что должно привести к:
Bar Foo Rec-Id
abcd efg 0
hijk lmn 1
Другие советы
Это мои наблюдения, а не полный ответ:
Я предполагаю (не пытаясь воспроизвести это самостоятельно), что может произойти несколько вещей, когда DataSet пытается «сгладить» иерархическую структуру до реляционной структуры данных.
1) думать о данных с точки зрения реляционной базы данных;нет очевидного поля первичного ключа для идентификации каждого из элементов Foo в коллекции, поэтому DataSet автоматически использует порядковый номер в файле в качестве автоматически создаваемого поля под названием Foo-Id.
2) На самом деле есть два элемента с именем «Foo», что, вероятно, объясняет создание странного имени для столбца «Foo-Id-0» (он автоматически сгенерировал уникальное имя для столбца — я думаю, вы могли бы подумать о это как отказоустойчивое поведение в DataSet).