I am reading a xml and finaly just need to remove the CDATA Infos in my results
For example: I get:
"<![CDATA[iPhone 4-Rückgaberecht: Deutsche Telekom kulant]]>"
just need "iPhone 4-Rückgaberecht: Deutsche Telekom kulant"
thx
chris
Edit to your answers:
I am not using NSXMLParser (thats the reason I make my own parser)
Found some suggestions with:
- (NSString *)stringByDecodingXMLEntities;
but dont know how to implement. I always get
> YourController may not respond to '-stringByDecodingXMLEntities" <
Ok, i solved it with that:
NSMutableString* resultString;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
resultString = [[NSMutableString alloc] init];
[resultString appendString:s];
}
- (NSString*)convertEntiesInString:(NSString*)s {
if(s == nil) {
NSLog(#"ERROR : Parameter string is nil");
}
NSString* xmlStr = [NSString stringWithFormat:#"<d>%#</d>", s];
NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSXMLParser* xmlParse = [[NSXMLParser alloc] initWithData:data];
[xmlParse setDelegate:self];
[xmlParse parse];
NSString* returnStr = [[NSString alloc] initWithFormat:#"%#",resultString];
return returnStr;
}
call: myConvertedString = [self convertEntiesInString:myOriginalString];
use
(void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
method instead of
(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
thats it
you could try a regex
replace <!\[CDATA\[(.*)\]\]> with $1
If you already have the String in String format with the you can remove it like so:
//Declare what you wish to remove
NSString * suffixTorRemove = #"<![CDATA[";
NSString * prefixToRemove = #"]]>";
//Now create a new string which uses your existing string and removes the declared occurrences above
NSString * newString = [yourString stringByReplacingOccurrencesOfString:suffixTorRemove withString:#""];
//Now the first part has changed, time to remove the second part
NSString * newString2 = [newString stringByReplacingOccurrencesOfString:prefixTorRemove withString:#""];
Quick and simple :-)
Related
I am new to Obj-c. I am adding parameter like text (the text may have special characters also)to url. But the url is showing nil, it's not taking value from string.
For example:
NSString*strUrl=[NSString stringWithFormat:#"hi how#!#$%^^&*()_=+ r u <>,./ where r u"];
NSString *strMainUrl=[NSString stringWithFormat:#"http://google.com/API/index.php action=listIt&data=%#",strUrl];
NSString *encodeStr = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:encodeStr];
NSLog(#" url is =%#",url);
But the url is showing nil value. It's not taking "encodeStr" value. How can I solve this problem.Please help me.
I tried with..
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:str] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
and also
strEncode=[strEncode stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
Modified example from here:
#import <Foundation/Foundation.h>
// In case you're unfamiliar, this is a category, which allows us to add methods
// to an existing class, even if we didn't create it. It's a nice alternative
// to subclassing.
//
// In this case, we're extending NSString
#interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
#end
#implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
#end
int main(int argc, char *argv[]) {
#autoreleasepool
{
NSString *raw = #"hi how#!#$%^^&*()_=+ r u <>,./ where r u";
// note also, that your string omits the '?' in the URL
NSString *url = [NSString stringWithFormat:#"http://google.com/API/index.php?action=listIt&data=%#",
[raw urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSURL *finalUrl = [NSURL URLWithString:url];
NSLog(#"%#", finalUrl);
}
}
Output:
http://google.com/API/index.php?action=listIt&data=hi%20how%40%21%23%24%25%5E%5E%26%2A%28%29_%3D%2B%20%20%20r%20u%20%3C%3E%2C.%2F%20where%20r%20u
Ok, say I have the string "hello my name is donald"
Now, I want to remove everything from "hello" to "is"
The thing is, "my name" could be anything, it could also be "his son"
So basically, simply doing stringByReplacingOccurrencesOfString won't work.
(I do have RegexLite)
How would I do this?
Use like below it will help you
NSString *hello = #"his is name is isName";
NSRange rangeSpace = [hello rangeOfString:#" "
options:NSBackwardsSearch];
NSRange isRange = [hello rangeOfString:#"is"
options:NSBackwardsSearch
range:NSMakeRange(0, rangeSpace.location)];
NSString *finalResult = [NSString stringWithFormat:#"%# %#",[hello substringToIndex:[hello rangeOfString:#" "].location],[hello substringFromIndex:isRange.location]];
NSLog(#"finalResult----%#",finalResult);
The following NSString Category may help you. It works good for me but not created by me. Thanks for the author.
NSString+Whitespace.h
#import <Foundation/Foundation.h>
#interface NSString (Whitespace)
- (NSString *)stringByCompressingWhitespaceTo:(NSString *)seperator;
#end
NSString+Whitespace.m
#
import "NSString+Whitespace.h"
#implementation NSString (Whitespace)
- (NSString *)stringByCompressingWhitespaceTo:(NSString *)seperator
{
//NSArray *comps = [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *comps = [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray *nonemptyComps = [[NSMutableArray alloc] init];
// only copy non-empty entries
for (NSString *oneComp in comps)
{
if (![oneComp isEqualToString:#""])
{
[nonemptyComps addObject:oneComp];
}
}
return [nonemptyComps componentsJoinedByString:seperator]; // already marked as autoreleased
}
#end
If you always know your string will begin with 'hello my name is ', then that is 17 characters, including the final space, so if you
NSString * hello = "hello my name is Donald Trump";
NSString * finalNameOnly = [hello substringFromIndex:17];
I have an XML parser and i want to trim whitespace and new lines before it goes to the app delegate. I know it only works with string, but how to do it for the elements inside the object. More important is it smart to do this or is it better to do a separate trimming
newString =[menu.enable stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
In
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSString *trimmedValue=[currentElementValue stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//NSLog(#"current value:%#",currentElementValue);
[aFile setValue:trimmedValue forKey:elementName];
}
it will trim every element before saving it to an object. Here, aFile is object
I've had my run ins with this issue myself, and it's not trivial. SriPriya's solution works but only if there are no newlines in the element content. This:
<foo>
hello
hi
</foo>
would (IIRC) come out as
#"hello\n hi"
when trimmed that way.
The solution I came up with to solve this (and there may be more elegant solutions out there - I'm all ears) is the following:
Presuming you're using NSXMLParser with a delegate class that handles the actual parsing (as in SriPriya's example above), where the -parser:foundCharacters: method is located, you would do:
- (NSString *)removeNewlinesAndTabulation:(NSString *)fromString appending:(BOOL)appending
{
NSArray *a = [fromString componentsSeparatedByString:#"\n"];
NSMutableString *res = [NSMutableString stringWithString:appending ? #" " : #""];
for (NSString *s in a) {
s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (s.length > 0
&& res.length > (appending ? 1 : 0)) [res appendString:#" "];
[res appendString:s];
}
return res;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (! currentElementValue) {
currentElementValue = [[NSMutableString alloc] initWithString:[self removeNewlinesAndTabulation:string appending:NO]];
} else {
[currentElementValue appendString:[self removeNewlinesAndTabulation:string appending:currentElementValue.length > 0]];
}
}
I know it looks like a lot of code for something this simple, but it will correctly turn
<foo>
hi there all
i am typing some
stuff
</foo>
into
#"hi there all i am typing some stuff"
which sounds like what you're looking for.
I have an string which is got from parsing an xml site.
http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500
I want to have an NSString function that will be able to parse the value of c.
Is there a default function or do i have to write it manually.
You could use Regular expression via RegExKit Lite:
http://regexkit.sourceforge.net/RegexKitLite/
Or you could separate the string into components (which is less nice):
NSString *url=#"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500";
NSArray *comp1 = [url componentsSeparatedByString:#"?"];
NSString *query = [comp1 lastObject];
NSArray *queryElements = [query componentsSeparatedByString:#"&"];
for (NSString *element in queryElements) {
NSArray *keyVal = [element componentsSeparatedByString:#"="];
if (keyVal.count > 0) {
NSString *variableKey = [keyVal objectAtIndex:0];
NSString *value = (keyVal.count == 2) ? [keyVal lastObject] : nil;
}
}
I made a class that does this parsing for you using an NSScanner, as an answer to the same question a few days ago. You might find it useful.
You can easily use it like:
URLParser *parser = [[[URLParser alloc] initWithURLString:#"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500"] autorelease];
NSString *c = [parser valueForVariable:#"c"]; //c=500
Try the following:
NSURL *url = [NSURL URLWithString:#"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500"];
NSMutableString *parameterString = [NSMutableString stringWithFormat:#"{%#;}",[url parameterString]];
[parameterString replaceOccurrencesOfString:#"&" withString:#";"];
// Convert string into Dictionary
NSPropertyListFormat format;
NSString *error;
NSDictionary *paramDict = [NSPropertyListSerialization propertyListFromData:[parameterString dataUsingEncoding:NSUTF8StringEncoding] mutabilityOption: NSPropertyListImmutable format:&format errorDescription:&error];
// Now take the parameter you want
NSString *value = [paramDict valueForKey:#"c"];
Here is the native iOS approach using NSURLComponents and NSURLQueryItem classes:
NSString *theURLString = #"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500";
NSArray<NSURLQueryItem *> *theQueryItemsArray = [NSURLComponents componentsWithString:theURLString].queryItems;
for (NSURLQueryItem *theQueryItem in theQueryItemsArray)
{
NSLog(#"%# %#", theQueryItem.name, theQueryItem.value);
}
I need to pass a timestamp with a timezone offset in a GET request, e.g.,
2009-05-04T11:22:00+01:00
This looks like a two arguments "2009-05-04T11:22:00" and "01:00" to the receiving PHP script (over which I've no control).
NSURL doesn't encode plus signs, but if I make an NSURL using the string
2009-05-04T11:22:00%2B01:00
the url I end up with contains:
2009-05-04T11:22:00%252B01:00
Any ideas how I can preserve my encoded plus sign or just plain prevent NSURL from encoding anything?
What worked for me was doing the UTF8 conversion, then replacing the + sign with %2B:
NSString *urlString =
[NSString stringWithFormat:#"%#/iphone/push/create?pn[token]=%#&pn[send_at]=%#",
kHTTPURL, appDelegate.deviceAPNToken, [dateTimeToUse description]];
urlString =
[[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
The string should be URL encoded.
Here is a category for NSString that will help:
NSString+Additions.h
#interface NSString (Additions)
- (NSString *)stringByURLEncoding;
NSString+Additions.m
#import "NSString+Additions.h"
#implementation NSString (Additions)
- (NSString *)stringByURLEncoding {
return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
}
Use NSString's stringByAddingPercentEscapesUsingEncoding: method on the text you want to include as an argument.
As its name implies, the method will convert return an auto-released string containing an url-safe version of the receiver.
Thought I may as well provide my workaround as an answer, as I don't think there's a good solution to the original problem.
The plus sign (+) is completely valid in a URL, so my solution was to convert the time to GMT and remove the timezone/DST offset from the string. I'll leave it as an exercise for the reader to determine the value of secondsFromGMT below as, in my case, it's always the same because I'm only interested in timestamps generated by a web server.
NSString *gmtWhen = [[self descriptionWithCalendarFormat:nil
timeZone:[NSTimeZone
timeZoneForSecondsFromGMT:secondsFromGMT
] locale:nil] stringByReplacingOccurrencesOfString:#" +0000" withString:#""];
Solution when using URLComponents (Swift 3):
var params = ["email": "user+ios-default#example.com", "name": "John Brown"]
var components = URLComponents(string: "http://www.example.com")!
components.path = "/login"
components.queryItems = params.map { URLQueryItem(name: $0, value: $1) }
let url_NoFix = components.url!
// http://www.example.com/login?name=John%20Brown&email=user+ios-default#example.com
let cs = CharacterSet(charactersIn: "+").inverted
let q = components.percentEncodedQuery?.addingPercentEncoding(withAllowedCharacters: cs)
components.percentEncodedQuery = q
let url_Fixed = components.url!
// http://www.example.com/login?name=John%20Brown&email=user%2Bios-default#example.com
encode you string by using below code
NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,NULL,(CFStringRef)#"+",kCFStringEncodingUTF8);
this will encode + of you string which will prevent replacement of + by %2b while posting data in post method
To get encoded plus (%2B) (It works with all charcters) use CFURLCreateStringByAddingPercentEscapes as
/**
get parameterized url from url and query parameters.
*/
+(NSString *)getParameterizedUrl:(NSString *)url withParameters:(NSDictionary *)queryDictionary
{
NSMutableArray *mutablePairs = [NSMutableArray array];
for (NSString *key in queryDictionary) {
[mutablePairs addObject:[NSString stringWithFormat:#"%#=%#", CTPercentEscapedQueryStringKeyFromStringWithEncoding(key, NSUTF8StringEncoding), CTPercentEscapedQueryStringValueFromStringWithEncoding(queryDictionary[key], NSUTF8StringEncoding)]];
}
return [[NSString alloc]initWithFormat:#"%#?%#",url,[mutablePairs componentsJoinedByString:#"&"]];
}
static NSString * const kCharactersToBeEscapedInQueryString = #":/?&=;+!##$()',*";
static NSString * CTPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
static NSString * const kCharactersToLeaveUnescapedInQueryStringPairKey = #"[].";
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}
static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}
And use in your code as
NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
[params setObject:#"2009-05-04T11:22:00+01:00" forKey:#"timestamp"];
NSString *urlString = [self getParameterizedUrl:#"http://www.example.com" withParameters:params];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];