GDataXMLNode.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /* Copyright (c) 2008 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. // These node, element, and document classes implement a subset of the methods
  16. // provided by NSXML. While NSXML behavior is mimicked as much as possible,
  17. // there are important differences.
  18. //
  19. // The biggest difference is that, since this is based on libxml2, there
  20. // is no retain model for the underlying node data. Rather than copy every
  21. // node obtained from a parse tree (which would have a substantial memory
  22. // impact), we rely on weak references, and it is up to the code that
  23. // created a document to retain it for as long as any
  24. // references rely on nodes inside that document tree.
  25. #import <Foundation/Foundation.h>
  26. // libxml includes require that the target Header Search Paths contain
  27. //
  28. // /usr/include/libxml2
  29. //
  30. // and Other Linker Flags contain
  31. //
  32. // -lxml2
  33. #import <libxml/tree.h>
  34. #import <libxml/parser.h>
  35. #import <libxml/xmlstring.h>
  36. #import <libxml/xpath.h>
  37. #import <libxml/xpathInternals.h>
  38. #if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4) || defined(GDATA_TARGET_NAMESPACE)
  39. // we need NSInteger for the 10.4 SDK, or we're using target namespace macros
  40. #import "GDataDefines.h"
  41. #endif
  42. #undef _EXTERN
  43. #undef _INITIALIZE_AS
  44. #ifdef GDATAXMLNODE_DEFINE_GLOBALS
  45. #define _EXTERN
  46. #define _INITIALIZE_AS(x) =x
  47. #else
  48. #define _EXTERN extern
  49. #define _INITIALIZE_AS(x)
  50. #endif
  51. // when no namespace dictionary is supplied for XPath, the default namespace
  52. // for the evaluated tree is registered with the prefix _def_ns
  53. _EXTERN const char* kGDataXMLXPathDefaultNamespacePrefix _INITIALIZE_AS("_def_ns");
  54. // Nomenclature for method names:
  55. //
  56. // Node = GData node
  57. // XMLNode = xmlNodePtr
  58. //
  59. // So, for example:
  60. // + (id)nodeConsumingXMLNode:(xmlNodePtr)theXMLNode;
  61. @class NSArray, NSDictionary, NSError, NSString, NSURL;
  62. @class GDataXMLElement, GDataXMLDocument;
  63. enum {
  64. GDataXMLInvalidKind = 0,
  65. GDataXMLDocumentKind,
  66. GDataXMLElementKind,
  67. GDataXMLAttributeKind,
  68. GDataXMLNamespaceKind,
  69. GDataXMLProcessingInstructionKind,
  70. GDataXMLCommentKind,
  71. GDataXMLTextKind,
  72. GDataXMLDTDKind,
  73. GDataXMLEntityDeclarationKind,
  74. GDataXMLAttributeDeclarationKind,
  75. GDataXMLElementDeclarationKind,
  76. GDataXMLNotationDeclarationKind
  77. };
  78. typedef NSUInteger GDataXMLNodeKind;
  79. @interface GDataXMLNode : NSObject {
  80. @protected
  81. // NSXMLNodes can have a namespace URI or prefix even if not part
  82. // of a tree; xmlNodes cannot. When we create nodes apart from
  83. // a tree, we'll store the dangling prefix or URI in the xmlNode's name,
  84. // like
  85. // "prefix:name"
  86. // or
  87. // "{http://uri}:name"
  88. //
  89. // We will fix up the node's namespace and name (and those of any children)
  90. // later when adding the node to a tree with addChild: or addAttribute:.
  91. // See fixUpNamespacesForNode:.
  92. xmlNodePtr xmlNode_; // may also be an xmlAttrPtr or xmlNsPtr
  93. BOOL shouldFreeXMLNode_; // if yes, xmlNode_ will be free'd in dealloc
  94. // cached values
  95. NSString *cachedName_;
  96. NSArray *cachedChildren_;
  97. NSArray *cachedAttributes_;
  98. }
  99. + (GDataXMLElement *)elementWithName:(NSString *)name;
  100. + (GDataXMLElement *)elementWithName:(NSString *)name stringValue:(NSString *)value;
  101. + (GDataXMLElement *)elementWithName:(NSString *)name URI:(NSString *)value;
  102. + (id)attributeWithName:(NSString *)name stringValue:(NSString *)value;
  103. + (id)attributeWithName:(NSString *)name URI:(NSString *)attributeURI stringValue:(NSString *)value;
  104. + (id)namespaceWithName:(NSString *)name stringValue:(NSString *)value;
  105. + (id)textWithStringValue:(NSString *)value;
  106. - (NSString *)stringValue;
  107. - (void)setStringValue:(NSString *)str;
  108. - (NSUInteger)childCount;
  109. - (NSArray *)children;
  110. - (GDataXMLNode *)childAtIndex:(unsigned)index;
  111. - (NSString *)localName;
  112. - (NSString *)name;
  113. - (NSString *)prefix;
  114. - (NSString *)URI;
  115. - (GDataXMLNodeKind)kind;
  116. - (NSString *)XMLString;
  117. + (NSString *)localNameForName:(NSString *)name;
  118. + (NSString *)prefixForName:(NSString *)name;
  119. // This is the preferred entry point for nodesForXPath. This takes an explicit
  120. // namespace dictionary (keys are prefixes, values are URIs).
  121. - (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error;
  122. // This implementation of nodesForXPath registers namespaces only from the
  123. // document's root node. _def_ns may be used as a prefix for the default
  124. // namespace, though there's no guarantee that the default namespace will
  125. // be consistenly the same namespace in server responses.
  126. - (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error;
  127. // access to the underlying libxml node; be sure to release the cached values
  128. // if you change the underlying tree at all
  129. - (xmlNodePtr)XMLNode;
  130. - (void)releaseCachedValues;
  131. @end
  132. @interface GDataXMLElement : GDataXMLNode
  133. - (id)initWithXMLString:(NSString *)str error:(NSError **)error;
  134. - (NSArray *)namespaces;
  135. - (void)setNamespaces:(NSArray *)namespaces;
  136. - (void)addNamespace:(GDataXMLNode *)aNamespace;
  137. - (void)addChild:(GDataXMLNode *)child;
  138. - (void)removeChild:(GDataXMLNode *)child;
  139. - (NSArray *)elementsForName:(NSString *)name;
  140. - (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)URI;
  141. - (NSArray *)attributes;
  142. - (GDataXMLNode *)attributeForName:(NSString *)name;
  143. - (GDataXMLNode *)attributeForLocalName:(NSString *)name URI:(NSString *)attributeURI;
  144. - (void)addAttribute:(GDataXMLNode *)attribute;
  145. - (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI;
  146. @end
  147. @interface GDataXMLDocument : NSObject {
  148. @protected
  149. xmlDoc* xmlDoc_; // strong; always free'd in dealloc
  150. }
  151. - (id)initWithXMLString:(NSString *)str options:(unsigned int)mask error:(NSError **)error;
  152. - (id)initWithData:(NSData *)data options:(unsigned int)mask error:(NSError **)error;
  153. - (id)initWithRootElement:(GDataXMLElement *)element;
  154. - (GDataXMLElement *)rootElement;
  155. - (NSData *)XMLData;
  156. - (void)setVersion:(NSString *)version;
  157. - (void)setCharacterEncoding:(NSString *)encoding;
  158. // This is the preferred entry point for nodesForXPath. This takes an explicit
  159. // namespace dictionary (keys are prefixes, values are URIs).
  160. - (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error;
  161. // This implementation of nodesForXPath registers namespaces only from the
  162. // document's root node. _def_ns may be used as a prefix for the default
  163. // namespace, though there's no guarantee that the default namespace will
  164. // be consistenly the same namespace in server responses.
  165. - (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error;
  166. - (NSString *)description;
  167. @end