Преобразование файлов с разделителями в XML
Автор:
Tiberius OsBurn
[Оригинал статьи] [Обсудить в форуме]
Перевод с английского: Виталий Готовцов
WWW: http://www.vitgot.narod.ru
Скачать исходный код к статье
Эта статья демонстрирует преобразование файла с разделителями в DataSet или файл XML. Чтобы продемонстрировать это я создал файл с таб-разделителями для обслуживания номеров в Роуч-мотеле [Roach-Motel - дешевый мотель с минимум услуг (прим. переводчика)].
Зачем проводить преобразование?
Файлы с таб-разделителями и с запятыми-разделителями когда-то были стандартным способом представления данных вне реляционной базы данных. С появлением XML разработчики получили возможность предоставлять свои данные в гораздо более богатом и более описательном окружении без сложностей и расходов реляционных баз данных. Преобразование наследия файлов с разделителями в формат XML позволяет разработчикам получить преимущество многих новых технологий, которые возникают вокруг XML.
Для чего сначала нужно преобразовывать в DataSet?
Хорошей особенностью .Net-объекта DataSet является его способность сохранять внутренние данные как XML. В прошлом разработчики Microsoft были вынуждены использовать функцию Split() для анализа своих файлов с разделителями, а затем снова собирать строки воедино в файл XML-формата. При работе с большими файлами это стало особенно скверной практикой. .NET-объект DataSet делает за нас бóльшую часть работы, чисто и быстро. Мы будем использовать метод GetXml() объекта DataSet, чтобы преобразовать DataSet-представление файла с разделителями в XML-представление.
Приступим
Мы собираемся динамически создать DataSet с помощью объекта StreamReader, объекта DataTable и объекта DataRows.
Давайте взглянем на фрагмент XML, полученный из файла с таб-разделителями:
<Kitchen xmlns="The_Roach_Motel">
<Room_Service>
<Room_Number>290</Room_Number>
<Breakfast>Bagel</Breakfast>
<Lunch>Pizza</Lunch>
<Dinner>Salmon</Dinner>
</Room_Service>
</Kitchen>
Действительно приятным в соединении XML/DataSet является то, как происходит объединение ADO и XML. Я могу определить пространство имен моего XML-представления хотя бы с помощью свойства объекта DataSet:
oDS.DataSetName = "Kitchen"
oDS.Namespace = "The_Roach_Motel"
В верхнем фрагменте XML обратите внимание, что именем DataSet становится имя корневого элемента, а свойство Namespace замечательно переносится в XML.
Затем мы добавим таблицу 'Room_Service'. Я стараюсь не использовать пробелы в названиях таблиц DataSet и элементов XML.
oDS.Tables.Add("Room_Service")
Мы воспользуемся объектом StreamReader чтобы открыть файл с разделителями.
Dim oSR As New StreamReader(strFilePath)
'Go to the top of the file
oSR.BaseStream.Seek(0, SeekOrigin.Begin)
Большая часть файлов с разделителями содержат заголовок или группу описывающих имен, которые идентифицируют столбцы данных. Мы собираемся выделить первую строку нашего файла и использовать названия заголовков столбцов в качестве столбцов нашего DataSet. После того, как мы добавим новую таблицу в наш DataSet, мы добавим названия столбцов в нашу новую таблицу.
Обратите внимание, что мы применяем функцию Split к нашему объекту StreamReader чтобы разделить названия столбцов.
'Add in the Header Columns
For Each strFields In oSR.ReadLine().Split(strDelimiter)
oDS.Tables(0).Columns.Add(strFields)
Next
После того, как мы добавили наши столбцы, мы можем начинать добавлять строки с данными. Нам будет необходимо подтвердить наш объект DataTable, установив связь с нашей таблицей в DataSet. После того, как это будет сделано, нам будет нужно создать объект DataRow. Объект DataRow содержит все данные строки и гарантирует, что данные размещены в правильных столбцах.
oTable = oDS.Tables(0)
While (oSR.Peek() > -1)
oRows = oTable.NewRow()
Обратите внимание, что снова и снова мы обращаемся к объекту StreamReader. Нет необходимости инициализировать его или начинать с начала - мы уже получили столбцы и теперь просто перемещаем данные из файла с разделителями. Я добавил intCounter, чтобы обозначить номер столбца, так как мы не знаем его имени в текущий момент.
For Each strFields In oSR.ReadLine().Split(strDelimiter)
oRows(intCounter) = strFields
intCounter = intCounter + 1
Next
intCounter = 0
После того, как мы заполнили объект DataRows данными, мы будем готовы добавить эту строку в объект DataTable.
oTable.Rows.Add(oRows)
End While
Все, что осталось сделать, это конвертировать DataSet в XML с помощью функции GetXML() и вернуть XML в виде строки. Вы можете сохранить эту строку в XML-файл, используя функцию WriteXML().
Добавлю, что XML и ADO.NET даруют разработчикам свободу, преобразовывая наследие форматов данных в удобные, доступные запросам документы. Я надеюсь, что вы найдете эту статью полезной и она поможет вам.
Код в целом
Imports System
Imports System.IO
Imports System.Collections
Imports System.Data
Imports System.Text
Module modXML
Sub Main()
Dim strXML As String
strXML = delimitedDataSet(vbTab, "c:/food.tab")
End Sub
Function delimitedDataSet(ByVal strDelimiter As String, _
ByVal strFilePath As String) As String
Dim oDS As New DataSet()
Dim strFields As String
Dim oTable As New DataTable()
Dim oRows As DataRow
Dim intCounter As Int32 = 0
Dim oRow As DataRow()
oDS.DataSetName = "Kitchen"
oDS.Namespace = "The_Roach_Motel"
oDS.Tables.Add("Room_Service")
Dim oSR As New StreamReader(strFilePath)
'Go to the top of the file
oSR.BaseStream.Seek(0, SeekOrigin.Begin)
'Add in the Header Columns
For Each strFields In oSR.ReadLine().Split(strDelimiter)
oDS.Tables(0).Columns.Add(strFields)
Next
'Now add in the Rows
oTable = oDS.Tables(0)
While (oSR.Peek() > -1)
oRows = oTable.NewRow()
For Each strFields In oSR.ReadLine().Split(strDelimiter)
oRows(intCounter) = strFields
intCounter = intCounter + 1
Next
intCounter = 0
oTable.Rows.Add(oRows)
End While
Return oDS.GetXml()
'oDS.WriteXml("c:/food.xml")
End Function
Файл с таб-разделителями
Вот файл, который я создал, чтобы предоставить обслуживание номеров в этом знаменитом отеле.
Room_Number Breakfast Lunch Dinner
290 Bagel Pizza Salmon
301 Orange Pizza Chicken ala King
349 Sweet Roll Salad Tofu and Vegetables
500 Omelet Sausage Veal
702 Eggs Tuna fish Cheese Sandwich
XML, полученный в результате
После того, как мы применили GetXml() к нашему DataSet, мы можем сохранить нашу строку как XML-файл.
<Kitchen xmlns="The_Roach_Motel">
<Room_Service>
<Room_Number>290</Room_Number>
<Breakfast>Bagel</Breakfast>
<Lunch>Pizza</Lunch>
<Dinner>Salmon</Dinner>
</Room_Service>
<Room_Service>
<Room_Number>301</Room_Number>
<Breakfast>Orange</Breakfast>
<Lunch>Pizza</Lunch>
<Dinner>Chicken ala King</Dinner>
</Room_Service>
<Room_Service>
<Room_Number>349</Room_Number>
<Breakfast>Sweet Roll</Breakfast>
<Lunch>Salad</Lunch>
<Dinner>Tofu and Vegetables</Dinner>
</Room_Service>
<Room_Service>
<Room_Number>500</Room_Number>
<Breakfast>Omelet</Breakfast>
<Lunch>Sausage</Lunch>
<Dinner>Veal</Dinner>
</Room_Service>
<Room_Service>
<Room_Number>702</Room_Number>
<Breakfast>Eggs</Breakfast>
<Lunch>Tuna fish</Lunch>
<Dinner>Cheese Sandwich</Dinner>
</Room_Service>
</Kitchen>