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