I'm parsing an xml file and I can NSLog the parsing, but my problem is that I need to get the image url`s from this "string":
<p>
<img class="alignnone size-thumbnail wp-image-81" title="ex4" src="http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex43-150x150.jpg" alt="" width="150" height="150" />
<img class="alignnone size-thumbnail wp-image-80" title="ex3" src="http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex32-150x150.jpg" alt="" width="150" height="150" />
<img class="alignnone size-thumbnail wp-image-79" title="ex2" src="http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex23-150x150.jpg" alt="" width="150" height="150" />
<img class="alignnone size-thumbnail wp-image-71" title="ex1" src="http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex12-150x150.jpg" alt="" width="150" height="150" />
</p>
Sorry for the plain code :)
what im using to extract the url´s is this code but its not working:
NSRange start = [item.imageGallery rangeOfString:#"http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/"];
NSRange end = [item.imageGallery rangeOfString:#"\" "];
int rangeLength = (int)(end.location - start.location);
NSString *hrefString = [[NSString alloc] initWithString:[item.imageGallery substringWithRange:NSMakeRange(start.location, rangeLength)]];
NSLog(#"image url = %#",hrefString);
Using a regular expression: "src=\"([^\"]+)\""
Here is some example code:
NSString *searchedString = #""
#"<p>"
#"<img class=\"alignnone size-thumbnail wp-image-81\" title=\"ex4\" src=\"http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex43-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" />"
#"<img class=\"alignnone size-thumbnail wp-image-80\" title=\"ex3\" src=\"http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex32-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" />"
#"<img class=\"alignnone size-thumbnail wp-image-79\" title=\"ex2\" src=\"http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex23-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" />"
#"<img class=\"alignnone size-thumbnail wp-image-71\" title=\"ex1\" src=\"http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex12-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" />"
#"</p>";
NSRange rangeOfString = NSMakeRange(0, [searchedString length]);
//NSLog(#"searchedString: %#", searchedString);
NSString *pattern = #"src=\"([^\"]+)\"";
NSError* error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSArray *matchs = [regex matchesInString:searchedString options:0 range:rangeOfString];
for (NSTextCheckingResult* match in matchs) {
NSLog(#"url: %#", [searchedString substringWithRange:[match rangeAtIndex:1]]);
}
NSLog Output:
url: http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex43-150x150.jpg
url: http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex32-150x150.jpg
url: http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex23-150x150.jpg
url: http://www.bubblesurprise.com/WPRESS_APP/wp-content/uploads/2012/02/ex12-150x150.jpg
here, I found it for you:
https://stackoverflow.com/a/5999294/1047258
The code from that answer:
NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray* matches = [detector matchesInString:source options:0 range:NSMakeRange(0, [source length])];
Then to handle the URL(s):
for (NSTextCheckingResult *match in matches) {
NSURL *url = [match URL];
// do whatever you want with the url
}
Related
How do I parse HTML file?
I'm getting an HTML file in the below code,I just want to get data in between BinarySecurityToken XML node.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if(_data)
{
//Here am getting the below HTML content
NSString* content = [[NSString alloc] initWithData:_data
encoding:NSUTF8StringEncoding];
}
}
<input type="hidden" name="wa" value="wsignin1.0" />
<input type="hidden" name="wresult"
value="<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:Lifetime>
<wsu:Created >2013-04-29T11:50:29.895Z</wsu:Created>
<wsu:Expires>2013-04-29T12:00:29.895Z</wsu:Expires>
</t:Lifetime>
<wsp:AppliesTo>
<EndpointReference>
<Address>urn:orin.converse</Address>
</EndpointReference></wsp:AppliesTo>
<t:RequestedSecurityToken>
<wsse:BinarySecurityToken>
aHR0cCUzYSUyZiUyZnNjaGVtYWd0Sjk0JTNk
</wsse:BinarySecurityToken>
Any ideas? Thanks in advance.
You can get using this code
NSRange divRange = [content rangeOfString:#"<wsse:BinarySecurityToken>" options:NSCaseInsensitiveSearch];
if (divRange.location != NSNotFound)
{
NSRange endDivRange;
endDivRange.location = divRange.length + divRange.location;
endDivRange.length = [content length] - endDivRange.location;
endDivRange = [content rangeOfString:#"</wsse:BinarySecurityToken>" options:NSCaseInsensitiveSearch range:endDivRange];
if (endDivRange.location != NSNotFound)
{
divRange.location += divRange.length;
divRange.length = endDivRange.location - divRange.location;
NSLog(#"BinarySecurityToken : %#",[content substringWithRange:divRange]);
}
}
Output :
aHR0cCUzYSUyZiUyZnNjaGVtYWd0Sjk0JTNk
You need and XML parser for that.
There's a tutorial here
For this particular case you can get the ranges of <wsse:BinarySecurityToken> and </wsse:BinarySecurityToken>, construct new range that will provide you location of the token, and get substring in that range.
Sample code:
NSRange openingTagRange = [htmlString rangeOfString:#"<wsse:BinarySecurityToken>"];
NSRange closingTagRange = [htmlString rangeOfString:#"</wsse:BinarySecurityToken>"];
NSRange tokenRange = NSMakeRange(openingTagRange.location + openingTagRange.length, closingTagRange.location - (openingTagRange.location + openingTagRange.length));
NSString *token = [htmlString substringWithRange:tokenRange];
Since your input comes from outside, you should probably check if the ranges' locations are not equal to NSNotFound.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSData * data = [NSData dataWithContentsOfFile:filePath];
TFHpple * tutorialsParser = [[TFHpple alloc] initWithHTMLData:data];
NSString *query = #"//div[#id='BinarySecurityToken']";
NSArray *nodes = [tutorialsParser searchWithXPathQuery:query];
for (TFHppleElement * element in nodes) {
NSLog(#"%#", element);
NSLog(#"%#", [element tagName]);
NSLog(#"%#", [element attributes]);
NSLog(#"%#", [element children]);
for (TFHppleElement *childElement in [element children]) {
NSLog(#"%#", childElement);
}
}
hope this will help you For more try this blog and Git Project Resource may help you and
Good blog by RAYWENDERLICH
or another option if you have all the HTML data in NSString you can get data between specific NSString with this function.
-(NSString*)stringBetweenString:(NSString*)start andString:(NSString)end {
NSRange startRange = [self rangeOfString:start];
if (startRange.location != NSNotFound) {
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [self length] - targetRange.location;
NSRange endRange = [self rangeOfString:end options:0 range:targetRange];
if (endRange.location != NSNotFound) {
targetRange.length = endRange.location - targetRange.location;
return [self substringWithRange:targetRange];
}
}
return nil;
}
I'm working with NSRegularExpression to read a text and find out hashtag.
This is NSString that I used in regularExpressionWithPattern.
- (NSString *)hashtagRegex
{
return #"#((?:[A-Za-z0-9-_]*))";
//return #"#{1}([A-Za-z0-9-_]{2,})";
}
And this is my method:
// Handle Twitter Hashtags
detector = [NSRegularExpression regularExpressionWithPattern:[self hashtagRegex] options:0 error:&error];
links = [detector matchesInString:theText options:0 range:NSMakeRange(0, theText.length)];
current = [NSMutableArray arrayWithArray:links];
NSString *hashtagURL = #"http://twitter.com/search?q=%23";
//hashtagURL = [hashtagURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
for ( int i = 0; i < [links count]; i++ ) {
NSTextCheckingResult *cr = [current objectAtIndex:i];
NSString *url = [theText substringWithRange:cr.range];
NSString *nohashURL = [url stringByReplacingOccurrencesOfString:#"#" withString:#""];
nohashURL = [nohashURL stringByReplacingOccurrencesOfString:#" " withString:#""];
[theText replaceOccurrencesOfString:url
withString:[NSString stringWithFormat:#"%#", hashtagURL, nohashURL, url]
options:NSLiteralSearch
range:NSMakeRange(0, theText.length)];
current = [NSMutableArray arrayWithArray:[detector matchesInString:theText options:0 range:NSMakeRange(0, theText.length)]];
}
[theText replaceOccurrencesOfString:#"\n" withString:#"<br />" options:NSLiteralSearch range:NSMakeRange(0, theText.length)];
[_aWebView loadHTMLString:[self embedHTMLWithFontName:[self fontName]
size:[self fontSize]
text:theText]
baseURL:nil];
Everything worked but it figured out a little issue when I use a string like this:
NSString * theText = #"#twitter #twitterapp #twittertag";
My code highlights only #twitter on each word and not the second part of it (#twitter #twitter(app) #twitter(tag)).
I hope someone will help me!
Thank you :)
The statement
[theText replaceOccurrencesOfString:url
withString:[NSString stringWithFormat:#"%#", hashtagURL, nohashURL, url]
options:NSLiteralSearch
range:NSMakeRange(0, theText.length)];
is replacing all instances of the string url with the replacement string. In the example you give, the first time through the loop, url is #"#twitter", and all three occurrences of that string within theText are replaced in one go. This is what theText looks like then:
#twitter #twitterapp #twittertag
So, of course, the next two times round the loop, the results are not quite what you expect... !
I think the fix is to limit the range of the replacement:
[theText replaceOccurrencesOfString:url
withString:[NSString stringWithFormat:#"%#", hashtagURL, nohashURL, url]
options:NSLiteralSearch
range:cr.range];
I have iphone app i have create a combo box i want that combo box should get value from xcode direct not from the html file so how to do that i am using following code to get combobox in html file
NSString *htmlPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"combo.html"];
NSString *htmlContent = [NSString stringWithContentsOfFile:htmlPath];
[webView loadHTMLString:htmlContent baseURL:nil];
combo.html:
<html>
<SELECT NAME="food" SIZE="10" style="width: 200px;" style="height: 100px ">
<OPTION VALUE="0">OK</OPTION>
<OPTION VALUE="1">Good</OPTION>
<OPTION VALUE="2">Best</OPTION>
<OPTION VALUE="3">Average</OPTION>
</SELECT>
</html>
I'm not 100% sure I understand the question, but I think that you're asking whether you can load an HTML file from your app bundle, then dynamically insert some different HTML content, from your app ... right?
If so, you can certainly do that.
First, we'll load the content into a mutable string:
NSString *htmlPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"combo.html"];
NSError *error;
NSMutableString *htmlContent = [NSMutableString stringWithContentsOfFile: htmlPath
encoding: NSUTF8StringEncoding
error: &error];
To insert a new option/value in the combo box, use something like this:
// look for the start of the combo box called "food"
NSRange range = [htmlContent rangeOfString: #"select name=\"food\""
options: NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
// search for the end tag </select>
range.length = htmlContent.length - range.location;
NSRange end = [htmlContent rangeOfString: #"</select>"
options: NSCaseInsensitiveSearch
range: range];
if (end.location != NSNotFound) {
NSString *newChoice = #"Awesome!"; // get this dynamically however you want
NSString *newOption =
[NSString stringWithFormat: #"<option value=\"4\">%#</option>\n", newChoice];
[htmlContent insertString: newOption atIndex: end.location];
NSLog(#"htmlContent = %#", htmlContent);
}
}
If you want to change the displayed value on one existing combo box option, then use code like this:
NSString *optionTwoHtml = #"<option value=\"2\">";
NSRange optionTwo = [htmlContent rangeOfString: optionTwoHtml
options: NSCaseInsensitiveSearch];
if (optionTwo.location != NSNotFound) {
int start = optionTwo.location + optionTwoHtml.length;
// search for the end tag </option>
optionTwo.length = htmlContent.length - optionTwo.location;
NSRange end = [htmlContent rangeOfString: #"</option>"
options: NSCaseInsensitiveSearch
range: optionTwo];
if (end.location != NSNotFound) {
NSString *newValue = #"Better Than Best!";
NSRange oldRange = NSMakeRange(start, end.location - start);
[htmlContent replaceCharactersInRange: oldRange
withString: newValue];
NSLog(#"htmlContent = %#", htmlContent);
}
}
Note this code just shows you what you can do. It's not optimized for performance. The HTML content you showed is very small, so it really wouldn't matter how efficient the parsing code is. If you use a much larger HTML file, you may want to optimize a little.
I load a html page in web view in this way:
NSString *description = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.mypage.html"] encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:pRova baseURL:nil];
I need to remove:
<img src="http://www.mypage/image" align="left" style="padding: 0px 10px 0px 0px; width: 301px; height: 280px;" alt="diaspora-uys" />
from NSString *description, to display the UIwebView without image and with only text.
How can i do this?
I solved in this way:
- (NSString *)flattenHTML:(NSString *)html {
NSScanner *theScanner;
NSString *gt =nil;
theScanner = [NSScanner scannerWithString:html];
while ([theScanner isAtEnd] == NO) {
// find start of tag
[theScanner scanUpToString:#"<img" intoString:NULL] ;
// find end of tag
[theScanner scanUpToString:#">" intoString:>] ;
}
html = [html stringByReplacingOccurrencesOfString:[ NSString stringWithFormat:#"%#>", gt] withString:#""];
return html;
}
1/ load the HTML content in a string
+(id)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)
2/ remove the <img /> tag in the string
3/ use loadHTMLString on you webView
Have a look at NSString reference
Instead of finding the <img /> tag in the HTML string, you can also perform a replace of <img by <img style='display:none;' to hide the image. But it will be still loaded...
check that to apply filter on url scheme :
Need to filter certain UIWebView requests and load them in different UIWebViews
I have modified the code and it's working perfectly. It will only remove src value. Remaining values and image tag are not modified
- (NSString *)flattenHTML:(NSString *)html {
NSScanner *theScanner;
NSString *gt = nil;
NSString *temp = nil;
theScanner = [NSScanner scannerWithString:html];
while ([theScanner isAtEnd] == NO) {
// find start of tag
[theScanner scanUpToString:#"<img" intoString:&temp];
//find the src tag
[theScanner scanUpToString:#"src" intoString:&temp];
[theScanner scanUpToString:#"=" intoString:&temp];
[theScanner scanUpToString:#" " intoString:>];
if (!gt) {
[theScanner scanUpToString:#">" intoString:>];
}
if (gt) {
html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"%#",gt] withString:#"=\"\""];
}
}
return html;
}
I'm developing an application for the iPhone that has inApp-mail sending capabilities. So far so good, but now I want to avoid html-injections as some parts of the mail are user-generated texts.
Basically I search for something like this:
// inits
NSString *sourceString = [NSString stringWithString:#"Hello world! Grüße dich Welt <-- This is in German."];
// ----- THAT'S WHAT I'M LOOKING FOR
// pseudo-code |
// V
NSString *htmlEncodedString = [sourceString htmlEncode];
// log
NSLog(#"source string: %#", sourceString);
NSLog(#"encoded string: %#", htmlEncodedString);
Expected output
source string: Hello world! Grüße dich Welt <-- This is in German.
encoded string: Hello world! Grüße dich Welt <-- This is in German.
I already googled and looked through several of SO's questions and answers, but all of them seem to be related to URL-encoding and that's not what I really need (I tried stringByAddingPercentEscapesUsingEncoding with no luck - it creates %C3%BC out of an 'ü' that should be an ü).
A code sample would be really great (correcting mine?)...
--
Thanks in advance,
Markus
Check out my NSString category for HTML. Here are the methods available:
- (NSString *)stringByConvertingHTMLToPlainText;
- (NSString *)stringByDecodingHTMLEntities;
- (NSString *)stringByEncodingHTMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
Thanks #all. I ended up using my own implementation:
//
// _________________________________________
//
// textToHtml
// _________________________________________
//
- (NSString*)textToHtml:(NSString*)htmlString {
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#">" withString:#">"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"""" withString:#"""];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"'" withString:#"'"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"\n" withString:#"<br>"];
return htmlString;
}
A little improvement on #Markus' code [Change <br /> to <p></p>, escape multiple spaces]
- (NSString*)textToHtml:(NSString*)htmlString {
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#">" withString:#">"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"""" withString:#"""];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"'" withString:#"'"];
htmlString = [#"<p>" stringByAppendingString:htmlString];
htmlString = [htmlString stringByAppendingString:#"</p>"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"\n" withString:#"</p><p>"];
// htmlString = [htmlString stringByReplacingOccurrencesOfString:#"\n" withString:#"<br />"];
while ([htmlString rangeOfString:#" "].length > 0) {
htmlString = [htmlString stringByReplacingOccurrencesOfString:#" " withString:#" "];
}
return htmlString;
}
I have been looking for a similar solution and this did the job for me
NSString* value = #"<&>";
const void* keys[1] = {CFSTR("somekey")};
const void* values[1] = {value};
CFDictionaryRef dicRef = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, nil, nil);
CFDataRef dataRef = CFPropertyListCreateData(kCFAllocatorDefault, dicRef, kCFPropertyListXMLFormat_v1_0, 0, NULL);
NSString *str = [[NSString alloc]initWithData:(NSData *)dataRef encoding:NSUTF8StringEncoding];
NSRange start =[str rangeOfString:#"string>"];
NSRange end =[str rangeOfString:#"</string"];
NSString *substr = [str substringWithRange:NSMakeRange(start.location+start.length, end.location-(start.location+start.length))];
[str release];
CFRelease(dicRef);
CFRelease(dataRef);
//Substring is now html entity encoded
I am using some of the features that is used when saving plist files. I hope this helps.
I'm expanding #Markus answer, because my case is i'm sending JSON string, so i need to added some escape, these are my function :
note :
the exception reference from w3schools. https://www.w3schools.com/tags/ref_urlencode.asp
- (NSString*)convertStringToHTMLEscape:(NSString*)stringContent
{
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"{" withString:#"%7B"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"}" withString:#"%7D"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"[" withString:#"%5B"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"]" withString:#"%5D"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"\"" withString:#"%22"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"\\" withString:#"%5C"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"/" withString:#"%2F"];
return stringContent;
}
Assuming the character encoding of the email supports Unicode - say UTF-8 - could you not just find and replace the occurrences of <, >, and & with <, >, and &?