#import /*! @header XMLTree XMLTree provides an Objective-C wrapper for Apple's built-in C-language XML parser and manipulation functions. */ /*! @class XMLTree @abstract Wraps some C-level functions from Apple for XML manipulation. @discussion

XMLTree provides an Objective-C wrapper for Apple's built-in C-language XML parser and manipulation functions. At the moment it only supports basic element and attribute information. However Apple's XML parser supports processing instructions, CDATA, and some other things I've never seen, so I'll add support for these as I go along.

I'm releasing this code into the Public Domain, so you can include it with your software regardless of the license you use. If you make any useful additions or bug fixes (especially with retain/release), we would all appreciate it if you would let me know so we can give the changes to everyone else too.

Author: Robert Harder, rob -at- iharder.net

version: 0.1

*/ @interface XMLTree : NSObject { CFXMLTreeRef _tree; CFXMLNodeRef _node; NSString *_lastUnknownSelector; } /*! @method dealloc @abstract Be a good citizen and clean up after ourselves. */ -(void)dealloc; /*! @method treeWithURL: @abstract Creates an autoreleased XMLTree with the contents of url. @discussion

This method does not return a properly-autoreleased object. Do not use it until we figure out what's wrong (or let me know if you found out.

Creates an autoreleased XMLTree with the contents of url or nil if there was an error. Of course the URL can be pointing to a file or a URL on the internet such as a GET command to a SOAP application. @param url The NSURL pointing to your XML data. @result An autoreleased XMLTree with the contents of url or nil if there was a problem. */ +(XMLTree *)treeWithURL:(NSURL *)url; /*! @method init @abstract Initializes and returns an XMLTree. @discussion Initializes and returns an XMLTree (with a retain count of 1). There isn't much point to creating an XMLTree this way until I add methods for manuallying adding XML nodes to the tree. @result An XMLTree (with a retain count of 1). */ -(XMLTree *)init; /*! @method initWithURL: @abstract Initializes and returns an XMLTree with the contents of url. @discussion Initializes and returns an XMLTree (with a retain count of 1) with the XML contents of url or nil if there is an error. @param url The NSURL pointing to your XML data. @result An XMLTree with a retain count of 1. */ -(XMLTree *)initWithURL:(NSURL *)url; /*! @method initWithCFXMLTreeRef: @abstract Initializes and returns an XMLTree with the internal data represented by ref. @discussion Initializes and returns an XMLTree (with a retain count of 1) with the internal CFXMLTreeRef data represented by ref. You probably won't ever need to call this yourself, but I call it internally and may move it to a Private API in the XMLTree.m file later. @param ref The CFXMLTreeRef containing the XML data. @result An XMLTree with a retain count of 1. */ -(XMLTree *)initWithCFXMLTreeRef:(CFXMLTreeRef)ref; /* ******** A B O U T S E L F ******** */ /*! @method name @abstract Returns the name of the root node in the tree. @discussion Returns the name of the root node in the tree or nil if a name is not appropriate in the current context such as if the "tree" is actually a single XML Processing Instruction node. @result The name of the root node in the tree.. */ -(NSString *)name; /*! @method xml @abstract Returns the XMLTree in an XML-looking form. @discussion Returns the XMLTree in an XML-looking form as performed by Apple's own CFXMLTreeCreateXMLData(...) method. @result The XMLTree in an XML-looking form. */ -(NSString *)xml; /*! @method description @abstract Returns a textual representation of the XMLTree. @discussion

Returns a textual representation of the XMLTree. The way the tree is interpreted depends on what kind of root node is represented by the receiver.

Listed below are the actions this method takes depending on the type of node this is.

Node TypeCFXMLNodeTypeCodeAction
DocumentkCFXMLNodeTypeDocument Recursively descends XML document piecing together the Text and CDATA nodes that are encountered. You can think of this as returning the plaintext version of the XML data, that is, with all tags removed.
ElementkCFXMLNodeTypeElement
AttributekCFXMLNodeTypeAttribute Default action: Whatever is returned by Apple's CFXMLNodeGetString(...) method.
Processing InstructionkCFXMLNodeTypeProcessingInstruction
CommentkCFXMLNodeTypeComment
TextkCFXMLNodeTypeText
CDATA SectionkCFXMLNodeTypeCDATASection
Document FragmentkCFXMLNodeTypeDocumentFragment
EntitykCFXMLNodeTypeEntity
Entity ReferencekCFXMLNodeTypeEntityReference
Document TypekCFXMLNodeTypeDocumentType
WhitespacekCFXMLNodeTypeWhitespace
Notation ElementkCFXMLNodeTypeNotation
Element Type DeclarationkCFXMLNodeTypeElementTypeDeclaration
Attribute List DeclarationkCFXMLNodeTypeAttributeListDeclaration
@result A textual representation of the XMLTree. */ -(NSString *)description; /*! @method attributeNamed: @abstract Returns the attribute named name. @discussion Returns the attribute named name or nil if no such attribute is found or the node is not an Element node. @param name The name of the attribute to return. @result The attribute named name. */ -(NSString *)attributeNamed:(NSString *)name; /*! @method attributes @abstract Returns a dictionary of all the attributes. @discussion Returns a dictionary of all the attributes in the node or nil if the node is not an Element node. @result A dictionary of all the attributes. */ -(NSDictionary *)attributes; /*! @method type @abstract Returns the type of node this is. @discussion Returns the type of node this is as defined by Apple's enum:
 enum CFXMLNodeTypeCode {
     kCFXMLNodeTypeDocument = 1,
     kCFXMLNodeTypeElement = 2,
     kCFXMLNodeTypeAttribute = 3,
     kCFXMLNodeTypeProcessingInstruction = 4,
     kCFXMLNodeTypeComment = 5,
     kCFXMLNodeTypeText = 6,
     kCFXMLNodeTypeCDATASection = 7,
     kCFXMLNodeTypeDocumentFragment = 8,
     kCFXMLNodeTypeEntity = 9,
     kCFXMLNodeTypeEntityReference = 10,
     kCFXMLNodeTypeDocumentType = 11,
     kCFXMLNodeTypeWhitespace = 12,
     kCFXMLNodeTypeNotation = 13,
     kCFXMLNodeTypeElementTypeDeclaration = 14,
     kCFXMLNodeTypeAttributeListDeclaration = 15
 };
 
@result The type of node this is. */ -(CFXMLNodeTypeCode)type; /* ******** A B O U T C H I L D R E N ******** */ /*! @method childAtIndex: @abstract Returns the child at the given index. @discussion Returns the child at the given index or nil if no such child exists or it doesn't make sense to have children (such as a Processing Instruction node). @param index The index of the child to get. @result The child at index. */ -(XMLTree *)childAtIndex:(int)index; /*! @method childNamed: @abstract Returns the first child named name. @discussion Returns the first child named name or nil if no such child exists or it doesn't make sense to have children (such as a Processing Instruction node). @param name The name of the child. @result The child named name. */ -(XMLTree *)childNamed:(NSString *)name; /*! @method descendentNamed: @abstract Returns the first descendent named name. @discussion Returns the descendent named name or nil if no such descendent exists or it doesn't make sense to have descendents (such as a Processing Instruction node). This is a depth-first search. @param name The name of the child. @result The child named name. */ -(XMLTree *)descendentNamed:(NSString *)name; /*! @method count @abstract Returns the number of children in the tree. @discussion Returns the number of children in the tree or -1 if there is no valid tree contained within (like if you tried to create an XMLTree with init). @result The number of children in the tree. */ -(int)count; @end /*! @function XMLTreeDescription @abstract Used internally to recursively generate tree descriptions. @param descr The mutable string that will have descriptions appended to it. @param tree The tree from which to make a description. @result A description of tree. */ CFStringRef XMLTreeDescription( CFMutableStringRef descr, CFXMLTreeRef tree ); /*! @function XMLTreeDescendentNamed @abstract Used internally to recursively search for a descendent. @param name The name of the descendent to search for. @param tree The tree in which to recursively search. @result The matching descendent or nil if no descendent is found. */ CFXMLTreeRef XMLTreeDescendentNamed( CFStringRef name, CFXMLTreeRef tree );