2010-04-16 61 views
0

我想解析一個XHTML文檔在iPhone上使用TBXML(儘管如果它會更容易,我會很樂意使用libxml2或NSXMLParser)。我需要提取正文的內容爲一系列的段落和維護聯標籤,例如:用內聯標籤解析XHTML

<!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

道歉的格式,我試圖編輯,但由於某種原因,我得到一個錯誤。 – JWood 2010-04-16 15:24:41

+0

user290796:因爲您試圖在需要使用代碼塊的地方使用內聯代碼字體。請參閱http://daringfireball.net/projects/markdown/syntax。 – 2010-04-16 18:20:40

回答

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狀態變量很重要時。解析器將不會收到元素的封閉'<'和'>'字符,因此您必須將elementName包含在'<'和'>'字符中並添加到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]; 
         } 
       } 
     } 
} 
+0

這就是我正在尋找的!謝謝! – JWood 2010-04-22 11:24:45