libxml的attributes参数用结构体表示

static void startElementSAX (void *ctx,

                             const xmlChar *localname,

                             const xmlChar *prefix,

                             const xmlChar *URI,

                             int nb_namespaces,

                             const xmlChar **namespaces,

                             int nb_attributes,

                             int nb_defaulted,

                             const xmlChar **attributes)

    [(LibXmlParser*)ctx elementFound:localname prefix:prefix 

uri:URI namespaceCount:nb_namespaces

namespaces:namespaces attributeCount:nb_attributes 

defaultAttributeCount:nb_defaulted attributes:(xmlSAX2Attributes *)attributes];

}

 

1.C指针格式解析属性

(const xmlChar **)attributes  :一个属性,是指针数组(attributes是地址)

   //attributes:  pointer to the array of (localname/prefix/URI/value/end)

              attribute values.

(xmlChar *)attributes[0]表示localname的值,等于(xmlChar **)(attributes+0)

(xmlChar *)attributes[1]表示prefix的值,等于(xmlChar **)(attributes+1)

attributes+=5;表示指针后移5位,到下一个属性;

if (strncmp((char*)localname, "system", sizeof("system")) == 0) {  
flag=2;
_currentItem = [NSMutableDictionary dictionary];
//查找属性
NSString *key,*val;
for (int i=0; i<nb_attributes; i++){
key = [NSString stringWithCString:(const char*)attributes[0] encoding:NSUTF8StringEncoding];
val = [[NSString alloc] initWithBytes:(const void*)attributes[3] length:(attributes[4] - attributes[3])
encoding:NSUTF8StringEncoding];
NSLog(@"key=%@,val=%@",key,val);
if ([@"Name" isEqualToString:key]) {
[_currentItem setObject:val forKey:@"name"];
break;
}
// [val release];
attributes += 5;//指针移动5个字符串,到下一个属性
}
[[_root objectForKey:@"items"] addObject:_currentItem];
return;
}



2.用结构体表示1中的属性指针数组

(xmlSAX2Attributes*)attributesStruct :结构体指针(指向结构体的地址)

可以用结构体代表1.中的指针数组

typedefstruct_xmlSAX2Attributes {

    const xmlChar* localname;

    const xmlChar* prefix;

    const xmlChar* uri;

    const xmlChar* value;

    const xmlChar* end;

}xmlSAX2Attributes;

 (xmlChar *)attributes[0]可以用

      (xmlSAX2Attributes*)attributesStruct[i].localname代替

//i :第 i 个属性

//i+1代表结构体数组整体偏移1位,指针偏移5位

attributes+5=attributesStruct[i+1];

 

例:

理解:解析<link rel="alternate" type="text/html" href="/eqcenter/recenteqsww/Quakes/us2008rkbc.php"/>

static const char *kLinkElementName = "link";

static NSUInteger kLinkElementNameLength = 5;

注(Element):length比字符串长度大1,这样指针就会指向下一位


static const char *kRelAlternateValueName = "alternate";

static NSUInteger kRelAlternateValueNameLength = 9;

注(Value):length和字符串长度相等


if(!strncmp((constchar *)localname, kLinkElementName, kLinkElementNameLength))

//(int)nb_attributes   :属性的个数(当前是3)

for(int i = 0;i < nb_attributes;i++) 

{

//(int)attributes[i].end:当前第i个属性  (值的结束)地址

//(int)attributes[i].value:当前第i个属性  (值的起始)地址

//(char*)attributes[i].value:当前第i个属性 以(值的起始)地址开头的字符串

int valueLength = (int) (attributes[i].end - attributes[i].value);

       NSString *value = [[NSString alloc] initWithBytes:attributes[i].value

                                                 length:valueLength

                                               encoding:NSUTF8StringEncoding];

if(0 == strncmp((const char*)attributes[i].localname, kRelAttributeName,
kRelAttributeNameLength))
{
if(0 == strncmp((const char*)attributes[i].value, kRelAlternateValueName,
kRelAlternateValueNameLength))
{
// now look for the href, once found break out of the inner loop
// then we go back and look for the title, updated and georss:point
for(int j = i+1; j < attributeCount; j++)
{
if(0 == strncmp((const char*)attributes[j].localname, kHrefAttributeName,
kHrefAttributeNameLength))
{
int urlLength = (int) (attributes[j].end - attributes[j].value);
NSString *url = [[NSString alloc] initWithBytes:attributes[j].value
length:urlLength
encoding:NSUTF8StringEncoding];
self.currentEarthquake.detailsURL = [NSString stringWithFormat:@"http://earthquake.usgs.gov/%@", url];
[url release];
break;
}
}
}
else
{
// we don't care about the related linke, only the alternate
[value release];
break;
}
}



}