воскресенье, 15 марта 2009 г.

XML, XPATH и Excel 2003

Есть хороший сайт с блогами , на нем очень рекомендую
блог derik_whittaker.
Правда у него есть один недостаток - блог на английском языке.

В посте от 07.08.2007 года Дерик описал как при помощи C#, XPath выполнить запрос к XML файлу, получающемуся из EXCEL 2003. Получить такой файл можно, сохранив книгу Excel в режиме как Table.xml.
Я это попробовал - работает. У меня таблица была с 1000 записями. Колонок 26, нужно выбрать 5.
В строке выбора я указал их позицию, считая с 1:

string wrkCell =

string.Format("//{0}:Worksheet[@{0}:Name='{1}']/{0}:Table/{0}:Row[*]/{0}:Cell[position()=2 or position()=18 or position()=22 or position()=25 or position()=26]/{0}:Data", ssNmspPref, nm1);

В переменной nm1 - имя листа, выбранного пользователем в диалоге.


В результате выбора

XPathNodeIterator itc = xpathNav.Select(wrkCell, nmspMan);
в itc получился набор отдельных объектов в количестве 1000строк * 5 = 5000.
Их я обработал в цикле при помощи itc.MoveNext(); Доступ к значению поля
как itc.Current.Value;
Надо представлять себе что, результат выбора itc к самим данным xml имеет такое же отношение как результат выполнения SQL к самой базе данных.
Если вам нужно по результатам выборки что то уточнить, надо снова формировать запрос и новой командой select формировать новый объект типа XPathNodeIterator.

Если в запросе к СУБД в выборку войдет запись, в которой нет нужного нам поля, то мы получим null. Здесь же результат просто не будет содержать этого поля. Как с этим разобраться?! В данном случае непонятно.

Excel при формирования этого xml файла, выгружает только те ячейки, которые присутствуют. Если ячейку не вводили, то ее нет, а следующая введенная ячейка имеет структуру <cell index="Номер колонки"> ... </cell>.
Мой запрос с этими пропусками полетел в трубу. А пропуски появились из-за того, что Excel формировал программист, который при null из базы, ничего не писал.

Для решения этой задачки, я написал процедуру, которая, пробегает по загруженному файлу и при обнаружении Cell с параметром Index= вставляет одну или несколько пустышек Cell.
Вставляю при помощи метода Родитель_Row.InsertBefore(Placebo, CellIndex).
Если нужно вставить несколько пустышек, то для каждой надо создавать новый объект!
При создании пустышки надо помнить о пространстве имен и не указывать "ss":

XmlElement Placebo = doc.CreateElement("","Cell", ssNmspURI);

XmlElement PlaData = doc.CreateElement("","Data", ssNmspURI);

PlaData.SetAttribute("Type",ssNmspURI, "String");

XmlText txt = doc.CreateTextNode("0");

PlaData.AppendChild(txt);

Placebo.AppendChild(PlaData);









Комментариев нет:

Отправить комментарий

X-Plane 11, 12 - любитель, Фото любитель со стажем

Постоянные читатели

Архив блога