Поток ориентированной библиотеки синтаксического анализатора XML с
несколькими полезными функциями.
Вебсайт: http://expat.sourceforge.net/
Поддерживаемые платформы: Win32, Linux
Заголовки: expat.bi
Версия заголовков: 1.95.8
Примеры: в examples/xml/
Пример
'' Инструмент командной строки - XML файловый
парсер на основе libexpat
'' Можно использовать zstring или wstring (libexpat или
libexpatw):
'#define XML_UNICODE
#include once "expat.bi"
#define FALSE 0
#define NULL 0
Const BUFFER_SIZE = 1024
Type Context
As Integer nesting
As XML_char * (BUFFER_SIZE+1) text
As Integer textlength
End Type
Dim Shared As Context ctx
'' Функция обратного вызова, вызывается когда начало XML тега
найдено
Sub elementBegin cdecl _
( _
ByVal userdata As Any Ptr, _
ByVal element As XML_char Ptr, _
ByVal attributes As XML_char Ptr Ptr _
)
'' Показать свое имя
Print Space(ctx.nesting);*element;
'' и его атрибуты (атрибуты даны как массив указателей
XML_char
'' во многом как argv, для каждого атрибута будет
'' элемент, представляющий имя и второй элемент,
представляющий
'' указанное значение)
While (*attributes)
Print " ";**attributes;
attributes += 1
Print "='";**attributes;"'";
attributes += 1
Wend
Print
ctx.nesting += 1
ctx.text[0] = 0
ctx.textlength = 0
End Sub
'' Функция обратного вызова, вызывается когда
конец XML тега найден
Sub elementEnd cdecl(ByVal userdata As Any Ptr, ByVal element As XML_char Ptr)
'' Показать текст собранный в функции
обратного вызова charData () ниже
Print Space(ctx.nesting);ctx.text
ctx.text[0] = 0
ctx.textlength = 0
ctx.nesting -= 1
End Sub
Sub charData cdecl _
( _
ByVal userdata As Any Ptr, _
ByVal chars As XML_char Ptr, _ '' примечание: не
заканчивающийся нулем
ByVal length As Integer _
)
'' Эта функция обратного вызова, по-видимому получает данные
между XML-тегами
'' (На самом деле?), в том числе новые строки и пробелы.
'' Добавить к нашему буферу, если там еще есть свободное место, хотя мы можем
напечатать его позже
If (length <= (BUFFER_SIZE - ctx.textlength)) Then
fb_MemCopy(ctx.text[ctx.textlength], chars[0], length * SizeOf(XML_char))
ctx.textlength += length
ctx.text[ctx.textlength] = 0
End If
End Sub
''
'' Main
''
Dim As String filename = Command(1)
If (Len(filename) = 0) Then
Print "Usage: expat <xmlfilename>"
End 1
End If
Dim As XML_Parser parser = XML_ParserCreate(NULL)
If (parser = NULL) Then
Print "XML_ParserCreate failed"
End 1
End If
''XML_SetUserData(parser, userdata_pointer)
XML_SetElementHandler(parser, @elementBegin, @elementEnd)
XML_SetCharacterDataHandler(parser, @charData)
If (Open(filename, For Input, As #1)) Then
Print "Could not open file: '";filename;"'"
End 1
End If
Static As UByte buffer(0 To (BUFFER_SIZE-1))
Dim As Integer reached_eof = FALSE
Do
Dim As Integer size = BUFFER_SIZE
Dim As Integer result = Get(#1, , buffer(0), size, size)
If (result Or (size <= 0)) Then
Print "File input error"
End 1
End If
reached_eof = (EOF(1) <> FALSE)
If (XML_Parse(parser, @buffer(0), size, reached_eof) = FALSE) Then
Print filename & "(" & XML_GetCurrentLineNumber(parser) & "): Error from XML parser: "
Print *XML_ErrorString(XML_GetErrorCode(parser))
End 1
End If
Loop While (reached_eof = FALSE)
XML_ParserFree(parser)