Форум: "Начинающим";
Текущий архив: 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.5 MB
Время: 0.004 c