expat CharacterDataHandler使用

来源:互联网 发布:浙江网络空间安全协会 编辑:程序博客网 时间:2024/06/07 07:22
现在要用expat解析一段XML文档,网上看到很多使用expat的,大多数只是处理element的name,attribute,唯独不见text是如何处理的,刚好我的XML中没有用到attribute,所以针对XML_CharacterDataHandler的处理,从初步的理解到熟练使用还是破费了点事。

这里做一个简单的记录。

我的XML文档:
<?xml version="1.0" encoding="UTF-8"?><Marker>    <MarkerName>subtype:caption</MarkerName>    <Parameters>        <Parameter>            <Name>data,en-US</Name>            <Type>String</Type>            <Value> CONTINUE TO PLAY </Value>        </Parameter>    </Parameters></Marker>

XML_SetCharacterDataHandler 注册了文本数据 handle ,在expat的sample中并没有使用这个函数,通过debug得知,这个函数在element开始和结束的时候都会被调用。

XML_CharacterDataHandler的函数声明:
typedef void(*XML_CharacterDataHandler)(void *userData,                            const XML_Char *s,                            int len);

element开始的时候,如果有文本数据,XML_CharacterDataHandler函数的s参数就是element的文本内容,需要通过len参数得到具体的长度,不然s就是当前文本后面的xml文档剩余部分。

element结束的时候,通过调试,我发现len的长度虽然大于0, 但是包含一个'\n'(因为我的XML文档里面element开始结束的<>后面我都加了换行),所以在我后面的代码中我将'\n'过滤掉了,不然text得到的数据还会有只有一个'\n'的情况。

    if ((len > 0) && (*s != '\n')) {
        text = AString(s, len);
    }

上面这几行代码就得到了text部分的文本。

注意:

  • 开始看到这个函数的时候,看到有人说什么处理字符集的,容易被误导,这个函数就是处理XML的文本数据的。
  • 通过userData参数得到depth似乎不能工作,参考sample.c中的int *depth = userData,然后操作depth都会导致crash。我的做法是在外部定义一个de全局的depth变量,startElement中加一 ,endElement减一。

下面是我的XML解析过程LOG信息:

 parse ID3 PRIV XML, created xml parser.
 parsed element : Marker, depth : 0
 parsed element : MarkerName, depth : 1
 parsed MarkerName's text data : subtype:caption
 element MarkerName's text is subtype:caption
 parsed element : MarkerName, depth : 0
 parsed element : Parameters, depth : 1
 parsed element : Parameter, depth : 2
 parsed element : Name, depth : 3
 parsed Name's text data : data,en-US
 parsed element : Name, depth : 2
 parsed element : Type, depth : 3
 parsed Type's text data : String
 parsed element : Type, depth : 2
 parsed element : Value, depth : 3
 parsed Value's text data :  CONTINUE TO PLAY
 caption text is :  CONTINUE TO PLAY
 parsed element : Value, depth : 2
 parsed element : Value, depth : 1
 parsed element : Value, depth : 0

可以看的出来我的xml的text数据都被正确解析出来了,下面是XML_CharacterDataHandler的实现:

privDataHandle(void *, char *s, int len){    AString text;    int curDepth = mXmlDepth - 1;    if (mParsedStatus != OK) return;    LOGV("parsed element : %s, depth : %d", mCurElementName.c_str(), curDepth);    if ((len > 0) && (*s != '\n')) {        text = AString(s, len);        LOGV("parsed %s's text data : %s\n", mCurElementName.c_str(), text.c_str());    }    switch (curDepth) {        case 0:            break;        case 1:            if (mCurElementName == AString("MarkerName")) {                if ((text == AString("subtype:caption"))) {                    LOGV("element MarkerName's text is subtype:caption ");                } else {                    LOGE("element MarkerName's text is not subtype:caption ");                    mParsedStatus = -EINVAL;                }            }            break;        case 2:            break;        case 3:            if (mCurElementName == AString("Value")) {                LOGV("caption text is : %s", text.c_str());            }            break;        default:            break;    }}

Reference:

  • http://www.cnblogs.com/Tue/archive/2010/01/18/1650258.html
  • http://book.luaer.cn/_164.htm
  • http://www.xml.com/pub/a/1999/09/expat/index.html
  • http://blog.csdn.net/caimouse/article/details/2455644[对 XML_CharacterDataHandler 描述是错误的]
  • http://blog.csdn.net/Aresky/article/details/353356



原创粉丝点击