В статье про SAX-парсер я рассказал что это такое и пообещал привести примеры не только на Visual Basic, но и на других языках программирования, в частности на Java. Ниже приведен такой пример - класс VXMLChecker, который умеет проверять XML-текст и XML-файл на соответствие XSD-схеме. Для этого у него есть два публичных метода: checkXML и checkFile.
воскресенье, 14 ноября 2010 г.
четверг, 11 ноября 2010 г.
SAX-парсер
В заметке Schematron и XSD я вскользь упомянул про SAX-парсер и то, что с его помощью можно проверить XML-файл на соответствие XSD-схеме. Здесь я постараюсь описать это подробнее на примере SAX-парсера от Microsoft.
Итак, способ разбора XML-файла с помощью SAX-парсера является событийно-ориентированным. Это означает, что приложение, которое использует SAX-парсер, получает от него уведомления о начале и об окончании XML-элементов, атрибутах, тексте внутри XML-узлов, ошибках разбора и т.д. - в том порядке, в котором SAX-парсер встретил их в XML-файле. При этом, SAX-парсер не сохраняет в памяти разобранные элементы, в отличие от интерфейса DOM, для которого строится и хранится в памяти объектная модель всего XML. Это делает SAX-парсер пригодным для потоковой обработки (например, для проверки или для загрузки куда-либо) XML-файлов любого размера.
Посмотрим на пример использования SAX-парсера в Visual Basic 6.0 (примеры на Java, C# обязательно будут в след. статьях).
Итак, способ разбора XML-файла с помощью SAX-парсера является событийно-ориентированным. Это означает, что приложение, которое использует SAX-парсер, получает от него уведомления о начале и об окончании XML-элементов, атрибутах, тексте внутри XML-узлов, ошибках разбора и т.д. - в том порядке, в котором SAX-парсер встретил их в XML-файле. При этом, SAX-парсер не сохраняет в памяти разобранные элементы, в отличие от интерфейса DOM, для которого строится и хранится в памяти объектная модель всего XML. Это делает SAX-парсер пригодным для потоковой обработки (например, для проверки или для загрузки куда-либо) XML-файлов любого размера.
Посмотрим на пример использования SAX-парсера в Visual Basic 6.0 (примеры на Java, C# обязательно будут в след. статьях).
суббота, 6 ноября 2010 г.
Failed to start Qt Designer
Столкнулся с проблемой - в NetBeans после обновления перестал запускаться Qt Designer с формулировкой: "Failed to start Qt Designer. Make sure it is installed and added to PATH".
Лечится в терминале командой:
export PATH=$PATH:/Developer/Applications/Qt/Designer.app/Contents/MacOS
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Лечится в терминале командой:
export PATH=$PATH:/Developer/Applications/Qt/Designer.app/Contents/MacOS
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
понедельник, 1 ноября 2010 г.
Schematron и XSD
Коротко про схематрон я написал в предыдущей статье. Здесь же речь пойдет об объединении схематрон-схемы и схемы XSD.
XSD-схема замечательно работает, когда необходимо провести форматный контроль XML файла. В нем есть все необходимые инструменты, чтобы проверить структуру XML-файла и соответствие данных определенным типам. Однако логический и арифметический контроль с помощью XSD-схемы осуществить нельзя. Для этого лучше всего подходит схематрон.
Однако, хранить две отдельных схемы (XSD и Schematron) в разных файлах неудобно. К тому же, существующие механизмы обработки XML-файлов (DOM- и SAX-парсеры) не умеют работать со схемами Schematron, а дважды проверять один и тот же XML по разным схемам не рационально (потребуется дважды "отпарсить" весь XML-файл).
Предлагается задавать правила проверки на языке Schematron в подэлементах <xs:appinfo> элементов <xs:annotation> XSD-схемы.
Пример:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://www.ascc.net/xml/schematron">
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<sch:pattern name="DocumentChecker">
<sch:rule context="Person">
<sch:assert test="@birthYear<1990">Birth year should be less than 1990.</sch:assert>
</sch:rule>
</sch:pattern>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:schema>
В этом примере мы видим утверждение на языке Schematron <sch:assert test="@birthYear<1990">Birth year should be less than 1990.</sch:assert>, которое должно проверяться в контексте XML-узла Person (<sch:rule context="Person">).
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
XSD-схема замечательно работает, когда необходимо провести форматный контроль XML файла. В нем есть все необходимые инструменты, чтобы проверить структуру XML-файла и соответствие данных определенным типам. Однако логический и арифметический контроль с помощью XSD-схемы осуществить нельзя. Для этого лучше всего подходит схематрон.
Однако, хранить две отдельных схемы (XSD и Schematron) в разных файлах неудобно. К тому же, существующие механизмы обработки XML-файлов (DOM- и SAX-парсеры) не умеют работать со схемами Schematron, а дважды проверять один и тот же XML по разным схемам не рационально (потребуется дважды "отпарсить" весь XML-файл).
Предлагается задавать правила проверки на языке Schematron в подэлементах <xs:appinfo> элементов <xs:annotation> XSD-схемы.
Пример:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://www.ascc.net/xml/schematron">
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<sch:pattern name="DocumentChecker">
<sch:rule context="Person">
<sch:assert test="@birthYear<1990">Birth year should be less than 1990.</sch:assert>
</sch:rule>
</sch:pattern>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:schema>
В этом примере мы видим утверждение на языке Schematron <sch:assert test="@birthYear<1990">Birth year should be less than 1990.</sch:assert>, которое должно проверяться в контексте XML-узла Person (<sch:rule context="Person">).
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Схематрон (Schematron)
Схематрон - это язык для проверки правильности утверждений о данных в формате XML.
Разработан Rick Jelliffe из Academia Sinica Computing Centre (http://xml.ascc.net/resource/schematron/schematron.html).
Валидация XML-файла по схематрон-схеме подобна трансформации этого XML-файла в соответствии с преобразованием на языке XSLT (eXtensible Stylesheet Language Transformations). На выходе получается текст, который по-сути является протоколом проверки.
На самом деле, любую схематрон-схему можно преобразовать в XSLT. Это свойство схематрона как раз и является самым главным его достоинством.
Пример схематрон-схемы приведен ниже:
<?xml version="1.0" encoding="US-ASCII"?>
<sch:schema xmlns:sch="http://www.ascc.net/xml/schematron">
<sch:title>Example Schematron Schema</sch:title>
<sch:pattern name="dog_pattern">
<sch:rule context="dog">
<sch:assert test="count(ear) = 2">A 'dog' element should contain two 'ear' elements.</sch:assert>
<sch:report test="bone">This dog has a bone.</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
Давайте разберем, что здесь что.
Тег <sch:schema> - схема, корневой тег схематрона.
Внутри тега схемы располагаются название схемы - тег <sch:title>, и шаблоны - теги <sch:pattern>. Атрибут шаблона name задает имя шаблона (в нашем примере: "dog_pattern").
Шаблон состоит из правил - тег <sch:rule>. Каждое правило применяется к узлу проверяемого по схематрон-схеме XML-файла, путь к которому (XPath) задается атрибутом context.
Правило состоит из утверждений (<sch:assert>) и сообщений (<sch:report>), которые имеют атрибут test - условие, формулируемое на языке XPath. Разница между ними в том, что если условие в сообщении истинно (в примере: test="bone"), то в выходной файл пишется текст сообщения (This dog has a bone.), а текст утверждения (A 'dog' element should contain two 'ear' elements.) пишется в выходной файл только если условие НЕ выполнено (test="count(ear) = 2").
понедельник, 25 октября 2010 г.
Oracle PL/SQL: Обработка ошибок
Создадим пакет и в нем тестовую процедуру, которая будет генерировать исключение (спецификацию пакета я опускаю, т.к. она очевидна):
create or replace package body VTESTPKG is
procedure Test1
is
begin
raise NO_DATA_FOUND;
end Test1;
end VTESTPKG;
Теперь, вызовем VTESTPKG.Test1 и запишем текст исключения в output:
begin
VTESTPKG.Test1;
exception
when others then
dbms_output.put_line(sqlerrm);
end;
Результат будет выглядеть так:
ORA-01403: данные не найдены
Код и текст ошибки в SQLERRM есть, однако нам бы очень хотелось увидеть место возникновения ошибки - в идеале номер строки и стек вызовов. Ниже приведен код функции ERR_WHENCE, которая возвращает место возникновения ошибки, и стандартный обработчик ошибок RaiseError, который я использую при обработке всех ошибок в моем коде на PL/SQL.
воскресенье, 24 октября 2010 г.
Oracle SQL: INSERT WHEN
В Oracle SQL есть интересная конструкция "INSERT WHEN...", о которой не все знают.
Во вторых, попробуем решить следующую задачу: пусть имеется таблица VTEST с полем A VARCHAR2(10) и нужно написать команду INSERT, которая будет вставлять значение 'AAA', отсутствующее в этой таблице (если такое значение уже есть, то новую запись создавать не нужно). Решение этой задачи может выглядеть примерно так:
INSERT INTO VTEST (A)
SELECT 'AAA' FROM dual
WHERE NOT EXISTS (SELECT * FROM VTEST WHERE A='AAA')
Такая конструкция, конечно, работает. Но плохо в ней то, что значение 'AAA' фигурирует дважды: в SELECT 'AAA' FROM dual и в SELECT * FROM VTEST WHERE A='AAA'.
А вот так выглядит та же операция, но с использованием INSERT WHEN:
INSERT
WHEN NOT EXISTS (SELECT * FROM VTEST WHERE A=A0)
THEN INTO VTEST (A) VALUES (A0)
SELECT 'AAA' A0 FROM dual
Здесь 'AAA' присутствует только 1 раз.
INSERT WHEN ([Condition]) THEN INTO [TableName] ([ColumnName]) VALUES ([VALUES]) ELSE INTO [TableName] ([ColumnName]) VALUES ([VALUES]) SELECT [ColumnName] FROM [TableName];
Во первых, эта конструкция позволяет с помощью одной каманды INSERT вставлять данные в разные таблицы.Во вторых, попробуем решить следующую задачу: пусть имеется таблица VTEST с полем A VARCHAR2(10) и нужно написать команду INSERT, которая будет вставлять значение 'AAA', отсутствующее в этой таблице (если такое значение уже есть, то новую запись создавать не нужно). Решение этой задачи может выглядеть примерно так:
INSERT INTO VTEST (A)
SELECT 'AAA' FROM dual
WHERE NOT EXISTS (SELECT * FROM VTEST WHERE A='AAA')
Такая конструкция, конечно, работает. Но плохо в ней то, что значение 'AAA' фигурирует дважды: в SELECT 'AAA' FROM dual и в SELECT * FROM VTEST WHERE A='AAA'.
А вот так выглядит та же операция, но с использованием INSERT WHEN:
INSERT
WHEN NOT EXISTS (SELECT * FROM VTEST WHERE A=A0)
THEN INTO VTEST (A) VALUES (A0)
SELECT 'AAA' A0 FROM dual
Здесь 'AAA' присутствует только 1 раз.
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Подписаться на:
Сообщения (Atom)