1.14.2. Creating a WAP Binary XML parser

When you create a parser you must take care to set up the token values for your tags correctly. These values only have a limited range. And the range also varies if attributtes are used or if it is an empty element.

ulxr_wbxmlparse.h contains constants for the ranges.

wbxml_TAG_FIRST, wbxml_TAG_LAST

boundaries for empty elements without attributes

wbxml_TAG_C_FIRST, wbxml_TAG_C_LAST

boundaries for elements with content but without attributes

wbxml_TAG_A_FIRST, wbxml_TAG_A_LAST

boundaries for empty elements with attributes. Currently not used as attributes are not supported.


boundaries for elements with content and attributes. Currently not used as attributes are not supported.

ulxmlrpcpp uses this technique to model the parsers for the XML-RPC tags MethodResponse or MethodCall which both include Value.

  class ValueParserWb : public WbXmlParser
    enum ValueWellKnownToken 1
      wbToken_Value     = wbxml_TAG_C_FIRST,   // 0x45 2
      wbToken_Array,                           // 0x46
      wbToken_Date,                            // 0x51
      wbToken_ValueParserLast                  // 0x52 3

  class MethodResponseParserWb : public ValueParserWb,
    enum RespWellKnownToken
      wbToken_MethodResponse = ValueParserWb::wbToken_ValueParserLast, // 0x52 4
      wbToken_Fault,                                                   // 0x53
      wbToken_Params,                                                  // 0x54
      wbToken_Param,                                                   // 0x55
      wbToken_ResponseParserLast                                       // 0x56


It is advisable to define the token values as enum structures.


The first item is assigned a defined start value.


You should also create an entry for the token beyond the last one.


This allows to create the start token for a potential deriving parser which uses the parent parser as "inner" element.

For more examples on the working method see the various *parse_wb.cpp files.

[Caution]There is one pitfall:


The first constructor in a chain of derived parsers must push an appropriate element onto the state stack because the parser methods rely upon being able to retrieve information about the current state.


The destructor on the other hand must clean up the stack.

    states.push(new ValueState(eNone)); 1

    while (states.size() != 0)2
      delete getTopValueState()->getValue();
      delete getTopValueState();