CEGUI之XML解析器——ExpatParser

CEGUI中资源文件加载,用到了XML文件解析,内置了几种解析接口,


这里分析一种:ExpatParser


相关类Attribute、Handler、Parser头文件,其中Serializer序列化是给CEGUILayoutEditor用的,使得layout资源文件能以XML文件格式保存。


大致流程为:

1、创建 2、设置   3 解析

处理接口(XMLHandler)有三个主要的函数。

//当一个元素开始的时候会调用

virtual void elementStart(const String& element, const XMLAttributes& attributes);

//当一个元素结束的时候会介绍

virtual void elementEnd(const String& element);

//当一个元素有文本元素的时候会调用,CEGUI中基本没有使用

virtual void text(const String& text);

什么是元素呢?前文已经讲过。这里在详细介绍一下,读者参看下面的代码。

<这是一个元素 属性1="属性值1" 属性2="属性值2">

这是元素对应的文本

</这是一个元素>

当遇到"<这是一个元素"时解析器会调用elementStart函数,当遇到"</这是一个元素>"时解析器会调用elementEnd。需要注意的是元素的结束亦可以这样定义,在<这是一个元素/>。文本信息在开始和结束之间。当遇到文本信息时解析器text函数。XMLAttributes类包含了这个元素对应的属性(在这个例子里面它包含了两个属性和值对)。

那如何加载并处理一个文件呢?首先需要建立一个处理这个文件的处理类,这个类必须派生自XMLHandler接口。然后在加载文件的时候先声明一个处理类的实例,然后调用XML解析模块的主处理函数,就可以处理一类文件了。


部分主要代码:

void ExpatParser::parseXMLFile(XMLHandler& handler, const String& filename, const String& /*schemaName*/, const String& resourceGroup)
{
   // All stuff goes here
    // 创建一个XML分析器
    XML_Parser parser = XML_ParserCreate(0); // Create a parser

    if (! parser)
    {
        throw GenericException("ExpatParser::parseXMLFile - Unable to create a new Expat Parser");
    }
//这一部分里的函数从解析器得到状态的信息或者为了设定解析器任意选择能灵活地被使用。
   XML_SetUserData(parser, (void*)&handler); // Initialise user data
// 设置每个XML元素出现和结束的处理函数。这里设置start为元素开始处理函数,end元素结束处理函数
    XML_SetElementHandler(parser, startElement, endElement); // Register callback for elements
// 为文本准备处理函数   
XML_SetCharacterDataHandler(parser, characterData); // Register callback for character data

    // Aquire resource using CEGUI ResourceProvider
// 使用CEGUI ResourceProvider获得解析的资源
    CEGUI::RawDataContainer rawXMLData;
    CEGUI::System::getSingleton().getResourceProvider()->loadRawDataContainer(filename, rawXMLData, resourceGroup);

    // Parse the data (note that the last true parameter tels Expat that this is the last chunk of the document
    // XML_Parser解析XML文档,把一充满着文件的缓冲区传给解析器
if ( ! XML_Parse(parser, reinterpret_cast<const char*>(rawXMLData.getDataPtr()), rawXMLData.getSize(), true))
    {
        System::getSingleton().getResourceProvider()->unloadRawDataContainer(rawXMLData);
        String exception (String((const utf8*)"ExpatParser::parseXMLFile - XML Parsing error '") +
                          String((const utf8*)XML_ErrorString(XML_GetErrorCode(parser))) +
                          String((const utf8*)"' at line ") +
                          PropertyHelper::uintToString(XML_GetCurrentLineNumber(parser)));
        // (We know it is a valid pointer, otherwise an exception would have been thrown above.)
        XML_ParserFree(parser);
        throw GenericException(exception);
    }

    // Release resource
    CEGUI::System::getSingleton().getResourceProvider()->unloadRawDataContainer(rawXMLData);
    // (We know it is a valid pointer, otherwise an exception would have been thrown above.)
   XML_ParserFree(parser);
}

元素开始处理函数

void ExpatParser::startElement(void* data, const char* element, const char** attr)
{
    XMLHandler* handler = static_cast<XMLHandler*>(data);
    XMLAttributes attrs;

    for(size_t i = 0 ; attr[i] ; i += 2)
        attrs.add((const utf8*)attr[i], (const utf8*)attr[i+1]);

    handler->elementStart((const utf8*)element, attrs);
}

元素结束处理函数

void ExpatParser::endElement(void* data, const char* element)
{
    XMLHandler* handler = static_cast<XMLHandler*>(data);
    handler->elementEnd((const utf8*)element);
}

文本处理函数

void ExpatParser::characterData(void *data, const char *text, int len)
{
    XMLHandler* handler = static_cast<XMLHandler*>(data);
    String str((const utf8*)text, static_cast<String::size_type>(len));
    handler->text(str);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值