Getting an XML value from an NSArray - ios

I'm currently using SMXMLDocument as my parser and so far it does a fantastic job parsing some XML files. The only problem that I have encountered is that it cannot seem to handle children with the same name, well at least in my case. But this parser can return the parsed XML as an NSArray.
The NSArray would look like this:
(
"<id>https://spreadsheets.goog\U2026</id>",
"<updated>2013-12-23T17:54:04.814Z</updated>",
"<category term=\"http://schemas.google.com/spreadsheets/2006#cell\" scheme=\"http://schemas.google.com/spreadsheets/2006\"/>",
"<title type=\"text\">A1</title>",
"<content type=\"text\">What?</content>",
"<link rel=\"self\" type=\"application/atom+xml\" href=\"https://spreadsheets.google.com/feeds/cells/some key/od6/private/full/R1C1\"/>",
"<link rel=\"edit\" type=\"application/atom+xml\" href=\"https://spreadsheets.google.com/feeds/cells/some key/18o84x\"/>",
"<cell row=\"1\" col=\"1\" inputValue=\"What?\">What?</cell>",
"<id>A1</id>",
"<status code=\"200\" reason=\"Success\"/>",
"<operation type=\"update\"/>")
So my question is, how would I get the values (and attributes) from the XML? If there is a way to tokenize this (ie going through the array as an NSString with a for-in loop or something) without having to use a big fancy library that would be great. Thanks in advance.
Update:
Here is the NSLog of what happens if I try to get id with SMXMLDocument:
Code:
SMXMLElement* testEntry = [feed childNamed:#"entry"];
NSLog(#"id: %#", [testEntry valueWithPath:#"id"]);
Output:
id: https://spreadsheets.google.com/feeds/cells/some key/od6/private/full/R1C1

After hours of battling with the code, I ended up using another parser (as a secondary) called SHXMLParser because of it's neat syntax. It is capable returning multiple values from nodes with the same name as an NSArray. From there I just compared the contents in the array and picked the one I wanted.

Related

Core Data imports attributes (from type NSString) with spaces and new line

I am importing some data using NSXMLParser from XML into Core Data.
xml looks like:
<Translation>
<LanguageCode>EN</LanguageCode>
<SurahName>Al Anfal (The Spoils of War)</SurahName>
<TranslatedText>Believers areā€¦</TranslatedText>
</Translation>
XML is ok i mean there aren't existing spaces there.
Then i want to display saved data on the App.
I concatenate different attributes into one string but it is not displayed in one line. (Integer values coming from other entity)
After debug, i realised that the attributes from type NSString added wrong into the core data. Namely they are containing spaces and line break.
I am using following code to concatenate string with integer values:
NSString *result = [NSString stringWithFormat:#"%# - :%i / %i",currentTranslation.surahName,surahNr,verseNr];
Result should be a string without line breaks, but surahName pushes following integers to the next line.
Result:
Al Anfal (The Spoils of War)
- :8 / 2
As you see this part "- :8 / 2" printed in new line which pushed by surahName.
I searched this problem but i didn't find something. I don't know what i am doing wrong.
I hope the description above was clear.
Thank you in advance
The problem should be in the way you parse your XML.
In the exemple you give, there is a new line caracter after the ending of each element.
Here is the delegate's methods called to parse your surahname line:
didStartElement (<SurahName>)
foundCharacters (Al Anfal (The Spoils of War))
didEndElement (</SurahName>)
foundCharacters (new line caracter)
In foundCaracters method you have to check if those caracters are in an opened element, and if this element is supposed to contain caracters.
If you determine caracters as usefull, add it to your current content, else don't use it.

Parsing XML issue

I have been trying to parse an XML file and all is going well except for one thing.
this is what my XML looks like:
<portfolio>
<item>
<image url="http://www.google.com" />
<title>my first title here.</title>
<desc>my first description here...</desc>
<date>15/07/2010</date>
<skills>skills 1, skills 2, skills 3</skills>
</item>
</portfolio>
I have been parsing: title, desc, date, and skills perfectly. The only issue I am having is parsing the image url. I am using this simple parser: https://github.com/robertmryan/Simple-XML-Parser
Anyway this is how I am setting up the element names to parse:
parser.elementNames = #[#"image", #"title", #"desc", #"date", #"skills"];
Anyway what do I feed into the element name for the image url based upon the XML snippet I gave above?
Thanks!
Edit:
I logged the dictionary it returns after trying the following 3 bits of code:
parser.attributeNames = #[#"image url"];
parser.attributeNames = #[#"image"];
parser.attributeNames = #[#"url"];
Each one of those (after being parsed), returns a dictionary which I logged as this:
dict keys: (
title,
skills,
desc,
date
)
So something is not working right.
The image element has a url attribute so you need to specify that you want the attribute to be parsed out too. Do this by setting the value of the attributeNames property on your parser.
This parser is really basic though so it has some limitations. Most important for you is that attributeNames is only used on the 'main' element (specified with rowElementName) so to do what you want to do you will need to edit the parser class to change that.

Showing unicode in the console in the right format

NSSet *subFolders = [_account subscribedFolders];
NSLog(#"subFolders: %#",subFolders);
Output:
...
"[Gmail]/\U05d8\U05d9\U05d5\U05d8\U05d5\U05ea",
"[Gmail]/\U05d7\U05e9\U05d5\U05d1"
...
Is there any way I can show the above text in its original language (Hebrew) ?
Things I tried:
changing the debugger from LLDB to GDB - Didn't work
Checking under preferences -> Text Editing UTF-* is selected
Thanks
There is no issue with displaying unicode characters in the console, so I would assume it's the way the string is getting into the set in the first place.
I would suggest iterating over all the objects inside subFolders with something like:
for( id object in [subFolders allObjects] ) {
//Print out the name of the item explicitly
}
Even if this doesn't work, it at least lets you work with the strings directly. If it's still printing out:
"[Gmail]/\U05d8\U05d9\U05d5\U05d8\U05d5\U05ea"
It would look as if you're being sent escaped unicode characters, and I would suggest this: https://stackoverflow.com/a/7861345/352891 - this may work directly on NSSet's description
NSString* strOld=[NSString stringWithFormat:#"%#",responseObject];
NSLog(#"%#",[NSString
stringWithCString:[strOld cStringUsingEncoding:NSUTF8StringEncoding]
encoding:NSNonLossyASCIIStringEncoding]);

NSString to NSDictionary

I have a string (from HTTP Header) and want to split it into a dictionary.
foo = \"bar\",baz=\"fooz\", beta= \"gamma\"
I ca not guarantee that the string is the same every time. Maybe there are spaces, maybe not, sometimes the double quotes are escaped, sometimes not.
So I found the solution in PHP with regular expressions. Unfortunately I can't convert it to work on iOS.
preg_match_all('#('.$key.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))#', $input, $hits, PREG_SET_ORDER);
foreach ($hits as $hit) {
$data[hit[1]] = $hit[3] ? $hit[3] : $hit[4];
}
Can anybody help me converting this to Objective-C?
I met a guy which is kinda RegEx guru. He explained the whole stuff and I got the following (working!!!!) solution in RegEx.
This gives me strings like foo="bar":
(?<=[,\\s])((realm|qop|nonce|opaque)=(?:([\"'])([^\2]+?)\2|([^\\s,]+)))
I then use another RegEx to split it by key and value to create a dictionary.

NSString componentsSeparatedByString "&" but ignore "& amp;"

Need to separate a string on & but not on &.
Is there a more elegant way to code this up rather than just replacing it first then separating it on the &? Like this...
query = [query stringByReplacingOccurrencesOfString:#"&" withString:#"~~~"];
NSArray * kvpairs = [query componentsSeparatedByString:#"&"];
NSMutableArray *mArr = [[NSMutableArray alloc] init];
for (NSString *kvp in kvpairs) {
[mArr addObject:[kvp stringByReplacingOccurrencesOfString:#"~~~" withString:#"&"]];
}
kvpairs = [NSArray arrayWithArray:mArr];
[mArr release];
You could use NSRegularExpression to enumerate through the string on a regular expression that matches & but not &, e.g.: #"&(?!amp;)". This will be more cumbersome than your current method but more exact, because it will work without modifying the original string and doesn't rely on a token value.
If you control the input to this method and can guarantee that ~~~ won't appear normally, there's nothing wrong with using ~~~. However if you don't control the input then you should attempt to parse the string without modification.
There isn't really anything wrong with that, as long as you are 100% sure that the string ~~~ won't occur in your query.
If you are not, my next step would be to implement a method to parse the string into an array. In this method, you could find each &, then check if it is followed by amp;. If it is, move on to the next one, if it is not, cut the string there and repeat.
HTML entities and references are really not a good thing to have hanging around in URLs. Unless there is a very good reason that HTML entities must be used, I would recommend using '%26' in the URL encode an ampersand.
That being said, you will run into problems if '&' is not the only HTML entity or reference, so unless you are absolutely sure '&' is the only one, you will need a more robust solution.

Resources