Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.02.13;
Скачать: [xml.tar.bz2];

Вниз

Проверить атрибуты в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.004 c
2-1290437922
rubius2008
2010-11-22 17:58
2011.02.13
Рисование с масштабированием в Delphi


15-1288635282
boriskb
2010-11-01 21:14
2011.02.13
Microsoft открывает центр разработок в Сколково


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


15-1288706428
mefodiy
2010-11-02 17:00
2011.02.13
Компонента печати штрих-кодов для Delphi 7


2-1290462726
Sarg77
2010-11-23 00:52
2011.02.13
Создание битовых массивов произвольной длинны





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский