/core/externals/update-engine/externals/gdata-objectivec-client/Source/XMLSupport/GDataXMLNode.h
C++ Header | 221 lines | 104 code | 48 blank | 69 comment | 0 complexity | b96c7a4944b6f88176a442793494a28e MD5 | raw file
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 16// These node, element, and document classes implement a subset of the methods 17// provided by NSXML. While NSXML behavior is mimicked as much as possible, 18// there are important differences. 19// 20// The biggest difference is that, since this is based on libxml2, there 21// is no retain model for the underlying node data. Rather than copy every 22// node obtained from a parse tree (which would have a substantial memory 23// impact), we rely on weak references, and it is up to the code that 24// created a document to retain it for as long as any 25// references rely on nodes inside that document tree. 26 27 28#import <Foundation/Foundation.h> 29 30// libxml includes require that the target Header Search Paths contain 31// 32// /usr/include/libxml2 33// 34// and Other Linker Flags contain 35// 36// -lxml2 37 38#import <libxml/tree.h> 39#import <libxml/parser.h> 40#import <libxml/xmlstring.h> 41#import <libxml/xpath.h> 42#import <libxml/xpathInternals.h> 43 44 45#ifdef GDATA_TARGET_NAMESPACE 46 // we're using target namespace macros 47 #import "GDataDefines.h" 48#endif 49 50#undef _EXTERN 51#undef _INITIALIZE_AS 52#ifdef GDATAXMLNODE_DEFINE_GLOBALS 53#define _EXTERN 54#define _INITIALIZE_AS(x) =x 55#else 56#if defined(__cplusplus) 57#define _EXTERN extern "C" 58#else 59#define _EXTERN extern 60#endif 61#define _INITIALIZE_AS(x) 62#endif 63 64// when no namespace dictionary is supplied for XPath, the default namespace 65// for the evaluated tree is registered with the prefix _def_ns 66_EXTERN const char* kGDataXMLXPathDefaultNamespacePrefix _INITIALIZE_AS("_def_ns"); 67 68// Nomenclature for method names: 69// 70// Node = GData node 71// XMLNode = xmlNodePtr 72// 73// So, for example: 74// + (id)nodeConsumingXMLNode:(xmlNodePtr)theXMLNode; 75 76@class NSArray, NSDictionary, NSError, NSString, NSURL; 77@class GDataXMLElement, GDataXMLDocument; 78 79enum { 80 GDataXMLInvalidKind = 0, 81 GDataXMLDocumentKind, 82 GDataXMLElementKind, 83 GDataXMLAttributeKind, 84 GDataXMLNamespaceKind, 85 GDataXMLProcessingInstructionKind, 86 GDataXMLCommentKind, 87 GDataXMLTextKind, 88 GDataXMLDTDKind, 89 GDataXMLEntityDeclarationKind, 90 GDataXMLAttributeDeclarationKind, 91 GDataXMLElementDeclarationKind, 92 GDataXMLNotationDeclarationKind 93}; 94 95typedef NSUInteger GDataXMLNodeKind; 96 97@interface GDataXMLNode : NSObject <NSCopying> { 98@protected 99 // NSXMLNodes can have a namespace URI or prefix even if not part 100 // of a tree; xmlNodes cannot. When we create nodes apart from 101 // a tree, we'll store the dangling prefix or URI in the xmlNode's name, 102 // like 103 // "prefix:name" 104 // or 105 // "{http://uri}:name" 106 // 107 // We will fix up the node's namespace and name (and those of any children) 108 // later when adding the node to a tree with addChild: or addAttribute:. 109 // See fixUpNamespacesForNode:. 110 111 xmlNodePtr xmlNode_; // may also be an xmlAttrPtr or xmlNsPtr 112 BOOL shouldFreeXMLNode_; // if yes, xmlNode_ will be free'd in dealloc 113 114 // cached values 115 NSString *cachedName_; 116 NSArray *cachedChildren_; 117 NSArray *cachedAttributes_; 118} 119 120+ (GDataXMLElement *)elementWithName:(NSString *)name; 121+ (GDataXMLElement *)elementWithName:(NSString *)name stringValue:(NSString *)value; 122+ (GDataXMLElement *)elementWithName:(NSString *)name URI:(NSString *)value; 123 124+ (id)attributeWithName:(NSString *)name stringValue:(NSString *)value; 125+ (id)attributeWithName:(NSString *)name URI:(NSString *)attributeURI stringValue:(NSString *)value; 126 127+ (id)namespaceWithName:(NSString *)name stringValue:(NSString *)value; 128 129+ (id)textWithStringValue:(NSString *)value; 130 131- (NSString *)stringValue; 132- (void)setStringValue:(NSString *)str; 133 134- (NSUInteger)childCount; 135- (NSArray *)children; 136- (GDataXMLNode *)childAtIndex:(unsigned)index; 137 138- (NSString *)localName; 139- (NSString *)name; 140- (NSString *)prefix; 141- (NSString *)URI; 142 143- (GDataXMLNodeKind)kind; 144 145- (NSString *)XMLString; 146 147+ (NSString *)localNameForName:(NSString *)name; 148+ (NSString *)prefixForName:(NSString *)name; 149 150// This is the preferred entry point for nodesForXPath. This takes an explicit 151// namespace dictionary (keys are prefixes, values are URIs). 152- (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error; 153 154// This implementation of nodesForXPath registers namespaces only from the 155// document's root node. _def_ns may be used as a prefix for the default 156// namespace, though there's no guarantee that the default namespace will 157// be consistenly the same namespace in server responses. 158- (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error; 159 160// access to the underlying libxml node; be sure to release the cached values 161// if you change the underlying tree at all 162- (xmlNodePtr)XMLNode; 163- (void)releaseCachedValues; 164 165@end 166 167 168@interface GDataXMLElement : GDataXMLNode 169 170- (id)initWithXMLString:(NSString *)str error:(NSError **)error; 171 172- (NSArray *)namespaces; 173- (void)setNamespaces:(NSArray *)namespaces; 174- (void)addNamespace:(GDataXMLNode *)aNamespace; 175 176// addChild adds a copy of the child node to the element 177- (void)addChild:(GDataXMLNode *)child; 178- (void)removeChild:(GDataXMLNode *)child; 179 180- (NSArray *)elementsForName:(NSString *)name; 181- (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)URI; 182 183- (NSArray *)attributes; 184- (GDataXMLNode *)attributeForName:(NSString *)name; 185- (GDataXMLNode *)attributeForLocalName:(NSString *)name URI:(NSString *)attributeURI; 186- (void)addAttribute:(GDataXMLNode *)attribute; 187 188- (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI; 189 190@end 191 192@interface GDataXMLDocument : NSObject { 193@protected 194 xmlDoc* xmlDoc_; // strong; always free'd in dealloc 195} 196 197- (id)initWithXMLString:(NSString *)str options:(unsigned int)mask error:(NSError **)error; 198- (id)initWithData:(NSData *)data options:(unsigned int)mask error:(NSError **)error; 199 200// initWithRootElement uses a copy of the argument as the new document's root 201- (id)initWithRootElement:(GDataXMLElement *)element; 202 203- (GDataXMLElement *)rootElement; 204 205- (NSData *)XMLData; 206 207- (void)setVersion:(NSString *)version; 208- (void)setCharacterEncoding:(NSString *)encoding; 209 210// This is the preferred entry point for nodesForXPath. This takes an explicit 211// namespace dictionary (keys are prefixes, values are URIs). 212- (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error; 213 214// This implementation of nodesForXPath registers namespaces only from the 215// document's root node. _def_ns may be used as a prefix for the default 216// namespace, though there's no guarantee that the default namespace will 217// be consistenly the same namespace in server responses. 218- (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error; 219 220- (NSString *)description; 221@end