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;
}
}
}