Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.02.13;
Скачать: CL | DM;

Вниз

Проверить атрибуты в xml-файле   Найти похожие ветки 

 
Scott Storch   (2010-11-23 17:45) [0]

Возникла необходимость проверять наличие атрибутов в xml-файле для определенных нодов. Хранить информацию об атрибутах, по каждому из необходимых мне нодов, пока думаю так:

TStrings.AddObject(<имя нода>, <список атрибутов (TStrings)>)

Алгоритм будет выглядеть примерно так:


// ...
for I := 0 to ChildNodes.Count - 1 do
begin
 if list_nodes_for_chk.IndexOf(ChildNodes[I].NodeName) <> -1 then
   // это нод для которого необходимо проверить наличие атрибутов
 begin
   Attrs := TStrings(list_nodes_for_chk.Objects[I]) // извлекаем список атрибутов
   // Проверка наличия атрибутов
 end;
end;
// ...


Ориентировочно необходимо будет проверять 3-5 нодов, для кажлого из которых 5-7 атрибутов. Городить десяток списков неправильно на мой взгляд, захламляется код. Что посоветуете?


 
Медвежонок Пятачок ©   (2010-11-23 17:54) [1]

TStrings.AddObject(<имя нода>, <список атрибутов (TStrings)>)

Зачем?
Зачем на болид F1 ставить карбюратор от горбатого запора и батарейное зажигание?

В том смысле что твой стринглист надо еще откуда-то заполнить.

берем еще один xml файл и пишем в него список xpath котрые должны вернуть не нулл.

и все.
енумерейтим список и делаем селектсинглнод в проверяемом документе.


 
Scott Storch   (2010-11-23 18:17) [2]


> берем еще один xml файл и пишем в него список xpath котрые
> должны вернуть не нулл.
>
> и все.
> енумерейтим список и делаем селектсинглнод в проверяемом
> документе.


можно простейший пример


 
Медвежонок Пятачок ©   (2010-11-23 22:43) [3]

пример чего?
управляющий файл проверок - xml документ.
в нем узлы.
в узлах прописаны выражения xpath.
грузим управляющий файл, получаем список узлов.
проходим по списку, читаем выражения xpath.
в проверяемом документе делаем selectsinglenode с уазанным xpath
если он вернул не нулл, идем дальше.
если селект вернул нулл, значит в проверяемом документе отсутствует контролируемый атрибут.
все.


 
Scott Storch   (2010-11-23 23:31) [4]


> управляющий файл проверок - xml документ.в нем узлы.в узлах
> прописаны выражения xpath. грузим управляющий файл


При таком подходе управляющий файл нужно будет распространять вместе с приложением, верно?. А что, если пользователь модифицирует содержимое управляеющего файла или вообще удалит его.


 
Плохиш ©   (2010-11-23 23:48) [5]


> Scott Storch   (23.11.10 23:31) [4]

Можно озвучить великий смысл этой задачи?


 
Медвежонок Пятачок ©   (2010-11-23 23:49) [6]

во первых в случае стринглиста файл тоже ниоткуда не возьмется. его надо будет распространять

во вторых, в случае, когда он будет xml документом его можно иметь в виде:
1. локальный дисковый файл
2. ресурс в exe/dll и загрузка через протокол res://
3. ресурс в сети или инете и загрузка его по шттп через url


 
Scott Storch   (2010-11-24 00:00) [7]


> во первых в случае стринглиста файл тоже ниоткуда не возьмется.
>  его надо будет распространятьво вторых, в случае, когда
> он будет xml документом его можно иметь в виде:1. локальный
> дисковый файл2. ресурс в exe/dll и загрузка через протокол
> res://3. ресурс в сети или инете и загрузка его по шттп
> через url


Хранить ввиде ресурса я как-то не подумал. Как раз то, что надо. Спасибо.


 
Scott Storch   (2010-11-24 14:08) [8]


> в узлах прописаны выражения xpath.


К примеру:

XML-файл:

<products>
    <product id="17" name="Холодильник Miele KFNS 4929 SDE ed"/>
    <product id="18" name="Утюг с парогенератором Philips GC8260">
</products>

Можете привести пример выражения, касательно проверки атрибута (к примеру в узле "product" нужно проверить наличие атрибута "id").

"/products/product/id<что дальше?>"

Только начал разбираться, не совсем все понятно, пример бы все прояснил.


 
Медвежонок Пятачок ©   (2010-11-24 14:36) [9]

iList := xdoc.selectNodes("/products/product[not(@id)]");
if iList.length > 0 then
ShowMessage("найдены узлы product, не имеющие атрибута id")
else
ShowMessage("Все узлы product в документе имеют атрибут id");

Без проверки:
Список всех продуктов в документе, у которых есть атрибут "id".
Все прочие продукты просто не принимаем во внимание

iList := xdoc.selectNodes("/products/product[@id]");


 
Scott Storch   (2010-11-24 14:48) [10]

круто, спасибо.

Тему можно закрывать


 
Scott Storch   (2010-11-25 12:05) [11]

Накатал для себя пример, на основе его буду писать алгоритм для своего приложения. Пример вроде работает как надо. Можете посмотреть, может лишнего чего написал или что-то можно упростить.

a.xml


<products>
<book id="7" name="" autor=""/>
<cd id="14" name=""/>
<book id="17" name="" autor=""/>
</products>


b.xml (управляющий)


<products>
<book>
 <queries>
  <query str="/products/book[not(@id)]"/>
  <query str="/products/book[not(@name)]"/>
  <query str="/products/book[not(@autor)]"/>
 </queries>
</book>
<cd>
 <queries>
  <query str="/products/cd[not(@id)]"/>
  <query str="/products/cd[not(@name)]"/>
 </queries>
</cd>
</products>



uses
 msxml;

{$R *.dfm}

procedure TForm14.FormCreate(Sender: TObject);
var
 xml_doc_a,
 xml_doc_b { управляющий xml }: IXMLDOMDocument;

 procedure analyze_xml_doc;
 var
   I, J: Integer;
   query_str: string;
   xml_node_prods_a, xml_node_prod_a, xml_node_queries, xml_node_query: IXMLDOMNode;
 begin
   xml_node_prods_a := xml_doc_a.documentElement;
   with xml_node_prods_a do
     { для каждого подузла "products" в a.xml проверяем
        наличие обязательных атрибутов }
     for I := 0 to childNodes.length - 1 do
     begin
       xml_node_prod_a := childNodes[I];
       { находим в b.xml узел "queries" для соответствующего узла из a.xml }
       xml_node_queries := xml_doc_b.selectSingleNode("/products/" +
         xml_node_prod_a.nodeName + "/queries");

       Assert(xml_node_queries <> nil);

       with xml_node_queries do
       begin
         for J := 0 to childNodes.length - 1 do
         begin
           xml_node_query := childNodes[J]; // Узел содержащий атрибут с XPath-выражением
           query_str := xml_node_query.attributes.item[0].nodeValue; // XPath-выражение

           // применяем XPath выражение к узлу из a.xml
           Assert(xml_node_prod_a.selectSingleNode(query_str) = nil,
             "Ошибка целостности! Отсутствует необходимый атрибут!");

         end;

       end;

     end;

end;

begin
 xml_doc_a := CoDOMDocument.Create;
 xml_doc_b := CoDOMDocument.Create;
 try

   Assert(xml_doc_a.load("D:\a.xml"));

   Assert(xml_doc_b.load("D:\b.xml")); // загружаем управляющий xml

   analyze_xml_doc;
 finally
   xml_doc_a := nil;
   xml_doc_b := nil;
 end;

end;


 
Медвежонок Пятачок ©   (2010-11-25 12:15) [12]

я бы для каждого квери ввел атрибут, который бы говорил, как следует использовать выражение и как интерпретировать результат селекта по его выражению xpath.

например:
- текущий xpath следует использовать в selectsinglenode. если он вернул нил то это ошибка (или наоборт).

- текущий xpath следует использовать в selectnodes. если длина списка не нулевая - это ошибка (или наоборт).

тогда алгоритм проверки сократится и его не надо будет переписывать слишком часто при меняющихся требованиях к структуре проверяемого документа.

а вот это бы убрал бы однозначно:
for I := 0 to childNodes.length - 1 do

так как здесь идет жесткая привязка алгоритма к структуре проверяемого документа


 
Scott Storch   (2010-11-25 12:26) [13]

не совсем понятно
> а вот это бы убрал бы однозначно:
> for I := 0 to childNodes.length - 1 do
>
> так как здесь идет жесткая привязка алгоритма к структуре
> проверяемого документа


не совсем понятно, можете поправить код, не обязательно, чтобы был рабочий, просто принцип увидеть


 
Медвежонок Пятачок ©   (2010-11-25 12:46) [14]

принцип простейший.

сначала выбираем все узлы из Б
selectnodes("//query")
дальше перебираем полученный список.
получаем выражение проверки и применяем его к документу А.

Но это еще не все.

Какой метод использовать с текущим выражением?
1.Может текущее выражение проверяет наличие обязательного атрибута конкретного узла. Тогда нужен selectsinglenode

2. Может текущее выражение ищет ноды, у которых нет определенного атрибута. Тогда нужно вызывать selectnodes

Далее.
Как следует интерпретировать результат селекта?
Допустим проверяли наличие недопустимого атрибута и получили nil
Но это могла быть и проверка наличия обязательного атрибута.
В первом случае нил - это "хорошо", а во втором случае "хорошо" - это не нил

Поэтому и надо добавить в узел квери два атрибута:
1. какой метод юзать:  selectnodes/selectsinglenode
2. как интерпретировать результат метода.


 
DiamondShark ©   (2010-11-25 12:51) [15]

А может уж лучше тогда схему написать, и валидировать документ по схеме?


 
Scott Storch   (2010-11-25 12:53) [16]

Обалдеть как все упрощается. Спасибо



Страницы: 1 вся ветка

Текущий архив: 2011.02.13;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.013 c
2-1290679150
Radgar
2010-11-25 12:59
2011.02.13
Ошибка при использовании Create


2-1290671015
Jacksotnik
2010-11-25 10:43
2011.02.13
stringgrid


15-1289165395
Юрий
2010-11-08 00:29
2011.02.13
С днем рождения ! 8 ноября 2010 понедельник


2-1290171238
Alex_C
2010-11-19 15:53
2011.02.13
Сохранить в одном файле несколько файлов


15-1288897823
Новичок
2010-11-04 22:10
2011.02.13
Ищу хорошую книгу по DelphiХ