Expat
 
面向流的XML解析器库具有几个有用的功能。

网站:http://expat.sourceforge.net/
支持平台:Win32,Linux
标题包括:expat.bi
标题版本:1.95.8
示例:在examples / xml /

例子

''基于libexpat的XML文件解析器命令行工具

''可以使用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标签开始时,由libexpat调用回调函数
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标签的结尾时,由libexpat调用回调函数
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

''
''主要
''

    Dim As String filename = Command(1)
    If (Len(filename) = 0) Then
        Print "用法:expat <xmlfilename >"
        End 1
    End If

    Dim As XML_Parser parser = XML_ParserCreate(NULL)
    If (parser = NULL) Then
        Print "XML_ParserCreate失败"
        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 "无法打开文件:'";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 "文件输入错误"
            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) & "):XML解析器出错:"
            Print *XML_ErrorString(XML_GetErrorCode(parser))
            End 1
        End If
    Loop While (reached_eof = FALSE)

    XML_ParserFree(parser)