while parse the HTML using NSXMLParser, not full data in iPhone - iphone

while parse the xml, not full data is getting after some word line end with read more
below three codes are in a single html page i spited that for better understanding.
i am parsing this in to my iPhone app using NSXMLParser.
problem is its parsing till <Style> below then it stops parsing from the text after that and completely ignores the data below the text!!!
<head>
<title>North Mobile County Middle School: Latest News > "1st Annual NMCK-8 Christmas Music Program"</title>
<META HTTP-EQUIV="X-UA-COMPATIBLE" CONTENT="IE=EmulateIE9">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="imagetoolbar" content="no">
<script type="text/javascript" src="JavaScripts.js"></script>
<script type="text/javascript" src="JavaScripts/NiceTitles.js"></script>
<style type="text/css">
i am splitting the code for better understanding
!--
body {
margin:0; padding:0;
background: #fff;}
body, td {
font: normal 13px "Trebuchet MS", Arial, Helvetica, sans-serif;
color:#333;}
/***********************************************/
/* Links
/***********************************************/
a:link, a:visited {
color: #CD0000;
text-decoration: none;}
a:hover, a:active {
color: #06f;
text-decoration: underline;}
img {border: 0;}
i am splitting the code for better understanding
#MainPageArea {padding: 0 15px 15px 15px}
</style>
<link href="http://images.pcmac.org/SiSFiles/Schools/AL/MobileCounty/NorthMobileMiddle/styles.css" rel="stylesheet" type="text/css">
<!--[if lt IE 7]>
<link href="Common/CommonIncludes/Template11/IEStyles.css" rel="stylesheet" type="text/css">
<![endif]-->
<link rel="Shortcut Icon" type="image/ico" href="http://images.pcmac.org/SiSFiles/Schools/AL/MobileCounty/NorthMobileMiddle/images/favicon.ico" />
</head>
<body class="DefaultPage">
<table align="center" cellpadding="0" cellspacing="0" width="986" border="0" id="PageWrapper">
<tr>
<td valign="top">
<div id="Header">
i am using code as below:
-(id) loadHtmlByURL:(NSString *)urlString
{
NSURL *url = [NSURL URLWithString:urlString];
NSData *nsData = [[NSData alloc] initWithContentsOfURL:url];
elementArray = [[NSMutableArray alloc] init];
parser = [[NSXMLParser alloc] initWithData:nsData];
parser.delegate = self;
[parser parse];
currentHTMLElement = [HtmlElement alloc];
return self;
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"%#",elementname);
currentHTMLElement = [[HtmlElement alloc] autorelease];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"%#",elementname);
if ([elementname isEqualToString:#"head"])
{
currentHTMLElement.tag = elementname;
currentHTMLElement.value = currentNodeContent;
[elementArray addObject:currentHTMLElement];
currentHTMLElement = nil;
currentNodeContent = nil;
// NSLog(#"x%#",elementArray);
}
can i know were i was struck

You should only use the NSXMLParser class to parse stuff that’s actually XML. HTML is not, except if it’s XHTML, which your source is not: The meta tags aren’t closed and your style tag starts with a comment that is never closed (which, I guess, is the reason why the parser never reads past that); also, the title’s text node contents should only contain escaped versions of > and " (the escape sequences being > and ").
If you’re in control of the HTML, try changing it to be XML- (and, thus, XHTML-) compliant. If you can’t change the HTML, try tag soup parsing, for example with hpple.

Here is the tutorial for Parsing HTML page
http://www.raywenderlich.com/14172/how-to-parse-html-on-ios

Related

How to get the span value from WebFrame in cocoa using objective c

I'm using the below code to get the html value after the web view loaded and able to get the response in string
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
WebDataSource *source = [frame dataSource];
NSData *data = [source data];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"String ::: %#",str);
}
Here's my html response in str :
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="hidden" hidden="true">
<span id="u-email">something#gmail.com</span>
</div>
</body>
</html>
I would need to get the hidden value of span :
for ex :
<span id="u-email">something#gmail.com</span>
How to get the span value(something#gmail.com) in Webview of cocoa framework ?
Please advice!
you can try stringByEvaluatingJavaScriptFromString
e.g.
NSString *function = [NSString stringWithFormat:#"document.getElementById('u-email').innerHTML"];
NSString *result = [webView stringByEvaluatingJavaScriptFromString:function];

Image not loading from css file

I have managed to display html in a UIWebView, but my problem is that the images are not displaying in my HTML, although my images, css, and javascript are all located in the same project folder.
Here is the my HTML:
<html>
<head>
<meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no, width = 320"/>
<link rel="stylesheet" type="text/css" href="site.css">
<script src="site.js" type="text/javascript" />
</head>
<body style="margin:0;padding:0;">
<div class="player"></div>
<div class="controller">
<div class="search"></div>
</div>
</body>
</html>
Here is my CSS:
body{
padding:0;
margin:0;
}
div.player{
width:320px;
height:180px;
}
div.controller{
float:left;
width:320px;
}
div.search{
float:left;
height:40px;
width:320px;
background-image:url('search.jpg');
}
And, finally, my Objective-C:
-(void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSString *htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[navigatorWindow loadHTMLString:htmlString baseURL:baseURL];
NSLog(#"%#",htmlString);
[super viewDidLoad];
}
Any idea what's going on here?
Make sure that search.jpg is adding to the Xcode Project. I believe that's the problem, because it is a local html file and not hosted on a server. Hope this helps.
background-image:url('search.jpg'); you have to give the full path of image here

Parsing XHTML with inline tags

I'm trying to parse an XHTML document using TBXML on the iPhone (although I would be happy to use either libxml2 or NSXMLParser if it would be easier). I need to extract the content of the body as a series of paragraphs and maintain the inline tags, for example:
<!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>
I need to extract the paragraph but maintain the <em>inline</em> content with the paragraph, all my testing so far has extracted that as a subelement without me knowing exactly where it fitted in the paragraph.
Can anyone suggest a way to do this?
Thanks.
Assumption 1. You are only interested in the data in the p (paragraph) element and that you are using NSXMLParser.
Assumption 2. You want to keep any element inside of p intact.
The strategy that you want to use is to create a state machine for your parser so that it knows when it needs to save data and when to ignore data as it is received.
Set up your NSXMLParser delegate using the sample code from Apple.
Your delegate will need an ivar BOOL inParagraph for tracking when data will be retained or discarded. The initial value of inParagaph is NO.
When your delegate receives the parser:didStartElement:namespaceURI:qualifiedName:attributes: message, if ([element isEqual:#"p"]) clear your receivedData variable and set inParagraph = YES
EDIT: receivedData is an NSMutableString. Fixed the code examples
At this point your parser delegate wants to save data received.
When the parser delegate receives the parser:foundCharacters: message, append the string to receivedData as in the sample code.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (inParagraph) [receivedData appendString:string];
}
When the parser encounters the inline element, the delegate will receive the parser:didStartElement:namespaceURI:qualifiedName:attributes: again. This is when the inParagraph state variable is important. The parser will not receive the enclosing '<' and '>' characters of an element, so you will have to wrap the elementName in the '<' and '>' characters and add to receivedData. Something like
- (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];
}
....
}
When the parser delegate receives the parser:didEndElement:namespaceURI:qualifiedName: message, it checks whether it is in the "p" element, if (inParagraph && ![elementName isEqual:#"p"], close the inline element. if ([elementName isEqual:#"p"]) add the contents of receivedData to the NSMutableArray holding your paragraphs.
- (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];
}
}
}
}

How to load Google Maps Faster in iPhone

in my iPhone application I'm loading the driving directions to a WebView from a bundled html page (because i can't find a way to load it directly to the MapKit), but it taking too much time to load, is there any better way to do so? Like in the iPhone default map application
code :
NSString *filePathString = [[NSBundle mainBundle] pathForResource:#"drive_index" ofType:#"html"];
NSMutableString *html = [[NSMutableString alloc] initWithContentsOfFile: filePathString];
[html replaceOccurrencesOfString: #"varLocation1" withString:loc1
options: NSLiteralSearch range: NSMakeRange(0, [html length])];
[html replaceOccurrencesOfString: #"varLocation2" withString:loc2
options: NSLiteralSearch range: NSMakeRange(0, [html length])];
NSURL *aURL = [NSURL fileURLWithPath:filePathString];
[webView loadHTMLString:html baseURL:aURL];
and the html page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Map</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
var directionsPanel;
var directions;
var location1="varLocation1";
var location2="varLocation2";
function initialize() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(location1), 13);
directionsPanel = document.getElementById("route");
directions = new GDirections(map, directionsPanel);
directions.load('from: ' + location1 +' to: '+ location2 );
}
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width:divice-width ; height:350px ; float:top; border: 1px solid black;"></div>
<div id="route" style="width:divice-width; border; 1px solid black;"></div>
</body>
</html>
Have a look at this answer:
Showing Driving Directions in MapKit
It says a way to use the Map Kit (which doesn't include driving directions) and overlay lines directly on top. Here's the site they reference:
http://spitzkoff.com/craig/?p=65
You should definitely see if you can switch to V3 of the Google Maps API. It was specifically designed to load quickly on mobile browsers. The only problem (and it's a big one) is that it doesn't support directions yet.

to extract a part of the URl after XML parsing?

I am trying to parse an XML file in which an element named "description" is as given below:
<description>
<![CDATA[
<a href='http://www.okmagazine.com/posts/view/13756/'>
<img src='http://www.okmagazine.com/img/photos/thumbs/27044' />
</a>
<br />
Ashlee and Pete take their tiny tot to FAO Schwarz in NYC for some new toys.
<p> <strong>Pete Wentz</strong> and <strong>Ashlee Simpson Wentz</strong> made the new parent pilgrimage to New York’s FAO Schwarz today, where 6-month old <strong>Bronx Mowgli </strong>was the...]]>
</description>
What I want is to get the link in the tag <img src='http://www.okmagazine.com/img/photos/thumbs/27044'> using which I can display an image in my image view... How can I separate this string from the contents of description tag?
A part of code when parsing is as given below
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//NSLog(#"found characters: %#", string);
// save the characters for the current item...
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:#"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
}
}
Please help
regards
Arun
I've never used that exact framework, but what you have to keep in mind is that while it will notify you when it finds the CDATA, anything inside is just plain-text to the parser. So it looks like you want to implement foundCDATA. You'll get passed a NSData block, and from there you have to parse the contents. Now, you can use another parser to do that, but it's probably faster just to do manual substring.
Have you thought about using regexp?
NSString *str = #"<![CDATA[<a href='http://www.okmagazine.com/posts/view/13756/'><img src='http://www.okmagazine.com/img/photos/thumbs/27044' /></a><br />Ashlee and Pete take their tiny tot to FAO Schwarz in NYC for some new toys. <p> <strong>Pete Wentz</strong> and <strong>Ashlee Simpson Wentz</strong> made the new parent pilgrimage to New York’s FAO Schwarz today, where 6-month old <strong>Bronx Mowgli </strong>was the...]]>";
NSRange range = [str rangeOfString: #"<img src='"];
str = [str substringFromIndex: range.location + range.length];
range = [str rangeOfString: #"'"];
str =[str substringToIndex: range.location];
CFShow(str);
Attributes are passed in to the didStartElement delegate method of the parser as a dictionary of strings keyed by attribute name. Thus, you can extract the urls you want from the attributes using NSDictionary's objectForKey: with the attribute name as the key. i.e.:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName compare: #"img"] == NSOrderedSame) // check for <img ...> element
{
NSString* url = [attributeDictionary objectForKey:#"src"];
// url now contains the url you require from the HTML