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# обязательно будут в след. статьях).

Для начала в нашем проекте на VB нам необходимо подключить Reference “Microsoft XML, v6.0”.

Затем нам необходимо создать ClassModule - класс объекта, который будет принимать уведомления от SAX-парсера. Назовем его MySAXReader. Он должен реализовывать интерфейсы MSXML2.IVBSAXContentHandler и MSXML2.IVBSAXErrorHandler.

Implements MSXML2.IVBSAXContentHandler
Implements MSXML2.IVBSAXErrorHandler

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, _

strLocalName As String, strQName As String)

    Debug.Print “endElement: “ & strLocalName

End Sub

Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, _

strLocalName As String, strQName As String, ByVal oAttributes As MSXML2.IVBSAXAttributes)

    Debug.Print “startElement: “ & strLocalName

End Sub

Private Sub IVBSAXErrorHandler_error(ByVal oLocator As MSXML2.IVBSAXLocator, _
strErrorMessage As String, ByVal nErrorCode As Long)

    Debug.Assert “error: “ & strErrorMessage

End Sub

Методы IVBSAXContentHandler_startElement и IVBSAXContentHandler_endElement будут вызываться SAX-парсером в начале и в конце XML-элемента соответственно. В этих методах, а также в других методах интерфейсов MSXML2.IVBSAXContentHandler и MSXML2.IVBSAXErrorHandler, нужно реализовывать логику приложения. Это может быть, например, загрузка значений в базу данных. Или запись ошибок в лог.

Теперь сделаем у нашего класса публичный метод, который будет осуществлять обработку XML-файла, а заодно и проверку его по XSD-схеме. Вот код:

Public Sub VerifyFile(ByVal sXmlFileName As String, ByVal sSchemaFileName As String)
    Dim oSaxReader As MSXML2.SAXXMLReader60
    Dim oSC As MSXML2.XMLSchemaCache60
    Set oSaxReader = CreateObject(“MSXML2.SAXXMLReader.6.0”) ‘создаем объект SAXXMLReader
    Set oSaxReader.contentHandler = Me ‘Обработчик событий SAX-паресера -
                                                               ‘объект, реализующий интерфейс IVBSAXContentHandler
    Set oSaxReader.errorHandler = Me ‘Обработчик ошибок  -
                                                            ‘объект, реализующий интерфейс IVBSAXErrorHandler
    Set oSC = CreateObject(“MSXML2.XMLSchemaCache.6.0”) ‘Кэш XSD-схем
    oSC.Add “”, sSchemaFileName ‘Добавляем в кэш имя файла нашей XSD-схемы
    oSaxReader.putFeature “schema-validation”, True ‘Включаем проверку по схеме
    oSaxReader.putFeature “exhaustive-errors”, True ‘Включаем проверку всех ошибок
    oSaxReader.putProperty “schemas”, oSC ‘Связываем SAXXMLReader и XMLSchemaCache
    oSaxReader.parseURL sXmlFileName ‘Запускаем SAX-парсер
End Sub

===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru