I have this xml:
<AccountsList>
<Account
Cod="0000"
AccountNumber="12345"
AccountName="John"
AccountSecondName="Wilson" />
</AccountsList>
For parsing it I use
[TBXML valueOfAttributeNamed:#"Cod" forElement:element]
[TBXML valueOfAttributeNamed:#"AccountNumber" forElement:element]
[TBXML valueOfAttributeNamed:#"AccountName" forElement:element]
[TBXML valueOfAttributeNamed:#"AccountSecondName" forElement:element]
But if xml came without COD:
<AccountsList>
<Account
AccountNumber="12345"
AccountName="John"
AccountSecondName="Wilson"
/>
</AccountsList>
I have crash! How I can check exist
[TBXML valueOfAttributeNamed:#"Cod" forElement:element]
or not?
if struct don't help :(
if ([TBXML valueOfAttributeNamed:#"Cod" forElement:element])
It's always return TRUE
Solution:
Now I try to check for empty string and this help me.
if ([TBXML valueOfAttributeNamed:#"Cod" forElement:element] isEqualToString:#"")
You can use the following code for retrieving the attribute values:
TBXMLAttribute * attribute = element->firstAttribute;
//Checking attribute is valid or not
while (attribute)
{
//Here you can check the `Cod` attribute exist or not
NSLog(#"%#->%# = %#",[TBXML elementName:element],[TBXML attributeName:attribute], TBXML attributeValue:attribute]);
// Next attribute
attribute = attribute->next;
}
Related
So I am building an app that uses parse as a backend. I've written my own before but I figured I'll just save some time and use parse. I'm populating a table view with data from parse and that's fine. I want to grab the objectId from an dictionary built from an array from parse.
The output of my array is as follows:
<news_events:pdbIEvOteH:(null)> {\n eventDescription = \"This is a test description.\";\n eventMessage = \"This is a test message.\";\n eventTitle = \"Free Wi-Fi Now Available!\";\n}
The object ID is pdbIEvOteH in the example above. I at first tried getting the id by using:
NSString * objectId = [myDictionary objectForKey:#"objectId"]; But that returned null. I know it is not a problem with my dictionary because I can get other information. The problem is it looks like there is no key for objectId in the array above. As you can see it follows news_events.
I know you can get it with the PFObject but I'm not sure if I can populate a table with a PFObject.
So bottom line is how do I get the objectId.
In my didSelectRowAtIndexPath: method, I did the following:
PFObject *myObject = [parseArray objectAtIndex:indexPath.row];
NSString *objectId = [myObject objectId];
To get the Id of a particular PFObject.
In Swift:
var objectId = object.objectId
In Objective-C:
NSString *objectId = object.objectId;
"So bottom line is how do I get the objectId."
following is answer from 'Joe Blow' with actual/example code for ios.
i had similar issue. retrieving data with following code worked:
NSString *reporterOpinion = [NSString stringWithFormat:#"%#", [object objectForKey:#"reporterOpinion"]];
but trying to do objectForKey with objectId returned null:
NSString *objectId = [NSString stringWithFormat:#"%#", [object objectForKey:#"objectId]];
following 'Joe Blow' answer, the following code returned correct value for objectId:
NSString *objectId = object.objectId;
I have a complex long XHTML file, which contains CSS. Searching on google and on this site, I've found some libraries that can be useful on XHTML parsing:
NSXMLParser
TBXML
And some others
However, I'm wondering if there is any library for iPhone that can convert a xhtml + css document to a NSAttributedString (only the text, of course).
I have been thinking on that problem, and I have had some ideas, but I think it won't be very efficient. My main idea is formed by this steps:
Detect on the XTHML file all tags with an id or class attribute and get the range of the string where they have effect (I cannot achieve this).
Save all the CSS attributes on a NSDictionary, with more NSDictionary objects inside. Something like this:
mainDict {
object: dictionary {
object: #"#00ff00"
key: #"color"
object: #"1em"
key: #"font-size"
}
key: #"a id"
object: anotherDictionary {
...
}
key: #"another id"
}
Convert these CSS attributes dictionary on the NSAttributedStringattributes dictionary.
I know that this is complex, and I don't need you to provide the code (of course, if you provide it, it would be great), I only want the link to a library or, if it doesn't exist, some advice for create a parser myself.
Of course, if you need some more information, ask by comments.
Thanks you!!
It depends on your needs if this will do what you want, but DTCoreText has an HTML -> NSAttributedString converter. It's very specific for what DTCoreText wants to / needs to do, but it might at least point you in the right direction.
My way to parse an HTML string into NSAttributedString is to recursively append parsed node (and its childNodes) into an NSMutableAttributedString.
I am not ready to publish my full code anywhere yet. But hopefully this can give you some hints...
NSString+HTML.h
/* - toHTMLElements
* parse the string itself into a dictionary collection of htmlelements for following keys
* : #"attributedString" // html main body
* : #"insets" // images and/or videos with range info
* : #"as" // href with range info
*
*/
- (NSMutableDictionary*) toHTMLElements;
NSString+HTML.m
- (NSMutableDictionary*) toHTMLElements {
// …
// handle escape encoding here
// assume that NSString* htmlString is the processed string;
// …
NSMutableDictionary * htmlElements = [[NSMutableDictionary dictionary] retain];
NSMutableAttributedString * attributedString = [[[NSMutableAttributedString alloc] init] autorelease];
NSMutableArray * insets = [NSMutableArray array];
NSMutableArray * as = [NSMutableArray array];
[htmlElements setObject:attributedString forKey:HTML_ATTRIBUTEDSTRING];
[htmlElements setObject:insets forKey:HTML_INSETS];
[htmlElements setObject:as forKey:HTML_AS];
// parse the HTML with an XML parser
// CXXML is a variance of TBXML (http://www.tbxml.co.uk/ ) which can handle the inline tags such as <span>
// code not available to public yet, so write your own inline-tag-enabled HTML/XML parser.
CXXML * xml = [CXXML tbxmlWithXMLString:htmlString];
TBXMLElement * root = xml.rootXMLElement;
TBXMLElement * next = root->firstChild;
while (next != nil) {
//
// do something here for special treatments if needed
//
NSString * tagName = [CXXML elementName:next];
[self appendXMLElement:next withAttributes:[HTMLElementAttributes defaultAttributesFor:tagName] toHTMLElements:htmlElements];
next = next->nextSibling;
}
return [htmlElements autorelease];
}
- (void) appendXMLElement:(TBXMLElement*)aElement withAttributes:(NSDictionary*)parentAttributes toHTMLElements:(NSMutableDictionary*) htmlElements {
// do your parse of aElement and its attribute values,
// assume NSString * tagAttrString is the parsed html attribute string (either from "style" attribute or css file) for this tag like : width:200px; color:#123456;
// let an external HTMLElementAttributes class to handle the attribute updates from the parent node's attributes
NSDictionary * tagAttr = [HTMLElementAttributes updateAttributes: parentAttributes withCSSAttributes:tagAttrString];
// create your NSAttributedString styled by tagAttr
// create insets such as images / videos or hyper links objects
// then update the htmlElements for storage
// once this tag is handled, recursively visit and process the current tag's children
TBXMLElement * nextChild = aElement->firstChild;
while (nextChild != nil) {
[self appendXMLElement:nextChild withAttributes:tagAttr toHTMLElements:htmlElements];
nextChild = nextChild->nextSibling;
}
}
I'm parsing an xml file using TBXML.
my xml is like this:
<locations>
<location>
<id>1</id>
<name>hello</name>
</location>
<location>
...
</locations>
all works fine, but there is a big problem: sometimes the xml can "skip" the "name" tag, so, for example, there is something like this:
...
</location>
<location>
<id>43</id>
</location>
<location>
...
where is the problem?
that using this code
TBXMLElement *location = [TBXML childElementNamed:#"location" parentElement:root];
while (location){
TBXMLElement *id = [TBXML childElementNamed:#"id" parentElement:location];
TBXMLElement *name = [TBXML childElementNamed:#"name" parentElement:location];
... //do something
location = location -> nextSibling;
}
the app crashes reading the tag "name" because sometimes there isn't...
How can i solve it??
thanks!
The app is probably crashing because your ... //do something is assuming that name is none-nil. If the <name> element wasn't found in the XML, the name var in your code ends up being nil.
What is the code that you snipped out in the "do something" comment?
Btw, I found this info by googling for something like "tbxml check for child node existence" and finding the following page:
http://www.tbxml.co.uk/forum/viewtopic.php?f=4&t=12
I am parsing a XML file with a format of:
**NOTE: This is a very simplified version of the XML. There are 11 divisions, and 87 departments total
<division>
<name> Sciences </name>
<departments>
<department>
<name> Computer Science </name>
</department>
<department>
<name> Biology </name>
</department>
<department>
<name> Chemistry </name>
</department>
</department>
</division>
What I am hoping to do is display this info in a UITableView, with Division names as the Sections, and the department names within each appropriate section.
I have a NSDictionary called divisionDict which I want to store NSArrays for each division; containing the departments. I also have a NSMutableArray called departmentArray, which contains each of the departments. So essentially, I want a divisionDict filled with departmentArrays.
Here is my code for parsing the XML, which works perfect, I am just having trouble storing separate arrays in the dictionary. When it goes through the parse now, and I try to print out the elements in the array with key "Sciences", it prints the departments for every division, not just the Sciences.
if(node_divisions)
{
node_division = [TBXML childElementNamed:#"division" parentElement:node_divisions];
while (node_division)
{
node_divisionName = [TBXML childElementNamed:#"name" parentElement:node_division];];
node_departments = [TBXML childElementNamed:#"departments" parentElement:node_division];
node_department = [TBXML childElementNamed:#"department" parentElement:node_departments];
divisionName = [TBXML textForElement:node_divisionName];
while(node_department)
{
node_departmentName = [TBXML childElementNamed:#"name" parentElement:node_department];
departmentName = [TBXML textForElement:node_departmentName];
//add the department name to the array
[departmentArray addObject:departmentName];
node_department = node_department->nextSibling;
}
//add the departmentArray to the dictionary, using the division name as the key
[divisionDict setObject:departmentArray forKey:divisionName];;
node_division = node_division->nextSibling;
}
}
Any help is greatly appreciated!!! I know its something simple I am missing probably but I have been looking at this for too many hours now and I just can't see it. If you need any other info, just let me know, I tried to explain everything in detail.
Also, here is a picture that hopefully helps show what I am trying to describe:
http://i.stack.imgur.com/a9nSb.png
It looks like you're adding all of the departments for each division to the same array. I think you just need to create a new array for each division in the loop:
while (node_division)
{
departmentArray = [NSMutableArray array]; //add this line
I have implemented demo using TouchXml parser.Its working fine.But I want to parse xml like below.
example:
<Root>
<tag1></tag1>
<tag2>
<temp1></temp1>
<temp2></temp2>
<temp3></temp3>
</tag2>
<tag3></tag3>
</Root>
How to parse this type of example?
TouchXML is nice and easy to use. First you'll want to parse the document:
NSError *theError = NULL;
CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:input options:0 error:&theError] autorelease];
You can then query the structure of your document using XPath. For example to extract the Root element you might do this:
NSArray *foundRoots = [theXMLDocument nodesForXPath:#"//Root" error:&theError];
CXMLElement *root = [foundRoots objectAtIndex:0];
(You often get arrays back, so in your case you can just take the first element, assuming it exists in the document)
You can also do things like get all the child elements of an element. So if we wanted to get all the tags we could this:
NSArray *children = [root children];
Or we could get a tag with a particular name:
NSArray *tag1 = [root elementsForName:#"tag1"];
(Again you get an array, so do the right thing and check)
Does your data conform to any schema?