我正在尝试在iPhone上使用TBXML解析XHTML文档(尽管如果它更容易,我会很乐意使用libxml2或NSXMLParser)。我需要将主体内容作为一系列段落提取并维护内联标记,例如:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Title</title>
<link rel="stylesheet" href="css/style.css" type="text/css"/>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
</head>
<body>
<div class="body">
<div>
<h3>Title</h3>
<p>Paragraph with <em>inline</em> tags</p>
<img src="image.png" />
</div>
</div>
</body>
</html>
我需要提取段落但保留段落中的<em>inline</em>
内容,到目前为止我的所有测试都已将其作为子元素提取出来,而我并不知道它在段落中的确切位置。
有人可以建议这样做吗?
感谢。
答案 0 :(得分:1)
假设1.您只对p(段落)元素中的数据感兴趣并且您正在使用NSXMLParser。
假设2.你想保持p内的任何元素完整。
您要使用的策略是为解析器创建状态机,以便它知道何时需要保存数据以及何时忽略收到的数据。
使用Apple的示例代码设置NSXMLParser delegate
。
您的代表需要使用ivar BOOL inParagraph
来跟踪何时保留或丢弃数据。 inParagaph
的初始值为NO
。
当您的代理人收到parser:didStartElement:namespaceURI:qualifiedName:attributes:
条消息后,if ([element isEqual:@"p"])
清除您的receivedData
变量并设置inParagraph = YES
编辑:receivedData是一个NSMutableString。修复了代码示例
此时,parser delegate
想要保存收到的数据。
当parser delegate
收到parser:foundCharacters:
消息时,请将字符串附加到receivedData
,如示例代码中所示。
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (inParagraph) [receivedData appendString:string];
}
当解析器遇到内联元素时,委托将再次收到parser:didStartElement:namespaceURI:qualifiedName:attributes:
。这是inParagraph
状态变量很重要的时候。解析器不会收到封闭的'&lt;'和'&gt;'元素的字符,因此您必须将elementName
包装在'&lt;'中和'&gt;'字符并添加到receivedData
。像
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{ if (inParagraph)
{
NSString *inlineElementName = [NSString stringWithFormat:@"<%@>", elementName];
[receivedData appendString:inlineElementName];
}
....
}
当parser delegate
收到parser:didEndElement:namespaceURI:qualifiedName:
消息时,它会检查它是否在“p”元素if (inParagraph && ![elementName isEqual:@"p"]
中,关闭内联元素。 if ([elementName isEqual:@"p"])
将receivedData
的内容添加到保存段落的NSMutableArray
。
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (inParagraph)
{
if (![elementName isEqual:@"p"])
{
NSString *inlineElementName = [NSString stringWithFormat:@"</%@>", elementName];
[receivedData appendString:inlineElementName];
} else { // received closing </p> tag add receivedData to the paragraph array
[paragraphsArray addObject:[receivedData copy]];
[self setInParagraph:NO];
}
}
}
}