2010-04-16 4 views
0

Я пытаюсь разобрать XHTML-документ с использованием TBXML на iPhone (хотя я был бы рад использовать libxml2 или NSXMLParser, если было бы проще). Мне нужно, чтобы извлечь содержимое тела в виде ряда пунктов и поддерживать встроенные тег, например:Parsing 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

+0

user290796: Потому что вы пытались использовать встроенный шрифт кода, где вам нужно было использовать блок кода. См. Http://daringfireball.net/projects/markdown/syntax. –

ответ

1

Успение 1. Вас интересуют только данные в элементе p (paragraph) и что вы используете NSXMLParser.

Успение 2. Вы хотите сохранить любой элемент внутри p неповрежденным.

Стратегия, которую вы хотите использовать, заключается в создании конечного автомата для вашего синтаксического анализатора, чтобы он знал, когда ему нужно сохранять данные и когда игнорировать данные по мере их получения.

Настройте свой NSXMLParser delegate, используя образец кода от Apple. Ваш делегат будет нуждаться в ivar BOOL inParagraph для отслеживания, когда данные будут сохранены или отброшены. Начальным значением inParagaph является NO. Когда делегат получает parser:didStartElement:namespaceURI:qualifiedName:attributes: сообщения, if ([element isEqual:@"p"]) очистить ваши receivedData переменных и установить inParagraph = YES

EDIT: 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: сообщение, он проверяет, является ли он в элементе «р», 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

Смежные вопросы