- Update
This commit is contained in:
1 parent
d281d765ea
commit
5b074a5176
1261 files changed
+199158
-7303
No files matched your search
+18
@@ -0,0 +1,18 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !(TARGET_IPHONE_SIMULATOR)
|
||||
@import libxml;
|
||||
#else
|
||||
@import libxmlSimu;
|
||||
#endif
|
||||
|
||||
@interface NSString (DDXML)
|
||||
|
||||
/**
|
||||
* xmlChar - A basic replacement for char, a byte in a UTF-8 encoded string.
|
||||
**/
|
||||
- (const xmlChar *)xmlChar;
|
||||
|
||||
- (NSString *)stringByTrimming;
|
||||
|
||||
@end
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
#import "NSString+DDXML.h"
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
@implementation NSString (DDXML)
|
||||
|
||||
- (const xmlChar *)xmlChar
|
||||
{
|
||||
return (const xmlChar *)[self UTF8String];
|
||||
}
|
||||
|
||||
#ifdef GNUSTEP
|
||||
- (NSString *)stringByTrimming
|
||||
{
|
||||
return [self stringByTrimmingSpaces];
|
||||
}
|
||||
#else
|
||||
- (NSString *)stringByTrimming
|
||||
{
|
||||
NSMutableString *mStr = [self mutableCopy];
|
||||
CFStringTrimWhitespace((__bridge CFMutableStringRef)mStr);
|
||||
|
||||
NSString *result = [mStr copy];
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
Vendored
+196
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Welcome to KissXML.
|
||||
*
|
||||
* The project page has documentation if you have questions.
|
||||
* https://github.com/robbiehanson/KissXML
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/KissXML/wiki/GettingStarted
|
||||
*
|
||||
* KissXML provides a drop-in replacement for Apple's NSXML class cluster.
|
||||
* The goal is to get the exact same behavior as the NSXML classes.
|
||||
*
|
||||
* For API Reference, see Apple's excellent documentation,
|
||||
* either via Xcode's Mac OS X documentation, or via the web:
|
||||
*
|
||||
* https://github.com/robbiehanson/KissXML/wiki/Reference
|
||||
**/
|
||||
|
||||
#import "DDXMLNode.h"
|
||||
#import "DDXMLElement.h"
|
||||
#import "DDXMLDocument.h"
|
||||
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
// Since KissXML is a drop in replacement for NSXML,
|
||||
// it may be desireable (when writing cross-platform code to be used on both Mac OS X and iOS)
|
||||
// to use the NSXML prefixes instead of the DDXML prefix.
|
||||
//
|
||||
// This way, on Mac OS X it uses NSXML, and on iOS it uses KissXML.
|
||||
|
||||
#ifndef NSXMLNode
|
||||
#define NSXMLNode DDXMLNode
|
||||
#endif
|
||||
#ifndef NSXMLElement
|
||||
#define NSXMLElement DDXMLElement
|
||||
#endif
|
||||
#ifndef NSXMLDocument
|
||||
#define NSXMLDocument DDXMLDocument
|
||||
#endif
|
||||
|
||||
#ifndef NSXMLInvalidKind
|
||||
#define NSXMLInvalidKind DDXMLInvalidKind
|
||||
#endif
|
||||
#ifndef NSXMLDocumentKind
|
||||
#define NSXMLDocumentKind DDXMLDocumentKind
|
||||
#endif
|
||||
#ifndef NSXMLElementKind
|
||||
#define NSXMLElementKind DDXMLElementKind
|
||||
#endif
|
||||
#ifndef NSXMLAttributeKind
|
||||
#define NSXMLAttributeKind DDXMLAttributeKind
|
||||
#endif
|
||||
#ifndef NSXMLNamespaceKind
|
||||
#define NSXMLNamespaceKind DDXMLNamespaceKind
|
||||
#endif
|
||||
#ifndef NSXMLProcessingInstructionKind
|
||||
#define NSXMLProcessingInstructionKind DDXMLProcessingInstructionKind
|
||||
#endif
|
||||
#ifndef NSXMLCommentKind
|
||||
#define NSXMLCommentKind DDXMLCommentKind
|
||||
#endif
|
||||
#ifndef NSXMLTextKind
|
||||
#define NSXMLTextKind DDXMLTextKind
|
||||
#endif
|
||||
#ifndef NSXMLDTDKind
|
||||
#define NSXMLDTDKind DDXMLDTDKind
|
||||
#endif
|
||||
#ifndef NSXMLEntityDeclarationKind
|
||||
#define NSXMLEntityDeclarationKind DDXMLEntityDeclarationKind
|
||||
#endif
|
||||
#ifndef NSXMLAttributeDeclarationKind
|
||||
#define NSXMLAttributeDeclarationKind DDXMLAttributeDeclarationKind
|
||||
#endif
|
||||
#ifndef NSXMLElementDeclarationKind
|
||||
#define NSXMLElementDeclarationKind DDXMLElementDeclarationKind
|
||||
#endif
|
||||
#ifndef NSXMLNotationDeclarationKind
|
||||
#define NSXMLNotationDeclarationKind DDXMLNotationDeclarationKind
|
||||
#endif
|
||||
|
||||
#ifndef NSXMLNodeOptionsNone
|
||||
#define NSXMLNodeOptionsNone DDXMLNodeOptionsNone
|
||||
#endif
|
||||
#ifndef NSXMLNodeExpandEmptyElement
|
||||
#define NSXMLNodeExpandEmptyElement DDXMLNodeExpandEmptyElement
|
||||
#endif
|
||||
#ifndef NSXMLNodeCompactEmptyElement
|
||||
#define NSXMLNodeCompactEmptyElement DDXMLNodeCompactEmptyElement
|
||||
#endif
|
||||
#ifndef NSXMLNodePrettyPrint
|
||||
#define NSXMLNodePrettyPrint DDXMLNodePrettyPrint
|
||||
#endif
|
||||
|
||||
#endif // #if TARGET_OS_IPHONE
|
||||
|
||||
|
||||
|
||||
// KissXML has rather straight-forward memory management:
|
||||
// https://github.com/robbiehanson/KissXML/wiki/MemoryManagementThreadSafety
|
||||
//
|
||||
// There are 3 important concepts to keep in mind when working with KissXML:
|
||||
//
|
||||
//
|
||||
// 1.) KissXML provides a light-weight wrapper around libxml.
|
||||
//
|
||||
// The parsing, creation, storage, etc of the xml tree is all done via libxml.
|
||||
// This is a fast low-level C library that's been around for ages, and comes pre-installed on Mac OS X and iOS.
|
||||
// KissXML provides an easy-to-use Objective-C library atop libxml.
|
||||
// So a DDXMLNode, DDXMLElement, or DDXMLDocument are simply objective-c objects
|
||||
// with pointers to the underlying libxml C structure.
|
||||
// Then only time you need to be aware of any of this is when it comes to equality.
|
||||
// In order to maximize speed and provide read-access thread-safety,
|
||||
// the library may create multiple DDXML wrapper objects that point to the same underlying xml node.
|
||||
// So don't assume you can test for equality with "==".
|
||||
// Instead use the isEqual method (as you should generally do with objects anyway).
|
||||
//
|
||||
//
|
||||
// 2.) XML is implicitly a tree heirarchy, and the XML API's are designed to allow traversal up & down the tree.
|
||||
//
|
||||
// The tree heirarchy and API contract have an implicit impact concerning memory management.
|
||||
//
|
||||
// <starbucks>
|
||||
// <latte/>
|
||||
// </starbucks>
|
||||
//
|
||||
// Imagine you have a DDXMLNode corresponding to the starbucks node,
|
||||
// and you have a DDXMLNode corresponding to the latte node.
|
||||
// Now imagine you release the starbucks node, but you retain a reference to the latte node.
|
||||
// What happens?
|
||||
// Well the latte node is a part of the xml tree heirarchy.
|
||||
// So if the latte node is still around, the xml tree heirarchy must stick around as well.
|
||||
// So even though the DDXMLNode corresponding to the starbucks node may get deallocated,
|
||||
// the underlying xml tree structure won't be freed until the latte node gets dealloacated.
|
||||
//
|
||||
// In general, this means that KissXML remains thread-safe when reading and processing a tree.
|
||||
// If you traverse a tree and fork off asynchronous tasks to process subnodes,
|
||||
// the tree will remain properly in place until all your asynchronous tasks have completed.
|
||||
// In other words, it just works.
|
||||
//
|
||||
// However, if you parse a huge document into memory, and retain a single node from the giant xml tree...
|
||||
// Well you should see the problem this creates.
|
||||
// Instead, in this situation, copy or detach the node if you want to keep it around.
|
||||
// Or just extract the info you need from it.
|
||||
//
|
||||
//
|
||||
// 3.) KissXML is read-access thread-safe, but write-access thread-unsafe (designed for speed).
|
||||
//
|
||||
// <starbucks>
|
||||
// <latte/>
|
||||
// </starbucks>
|
||||
//
|
||||
// Imagine you have a DDXMLNode corresponding to the starbucks node,
|
||||
// and you have a DDXMLNode corresponding to the latte node.
|
||||
// What happens if you invoke [starbucks removeChildAtIndex:0]?
|
||||
// Well the undelying xml tree will remove the latte node, and release the associated memory.
|
||||
// And what if you still have a reference to the DDXMLNode that corresponds to the latte node?
|
||||
// Well the short answer is that you shouldn't use it. At all.
|
||||
// This is pretty obvious when you think about it from the context of this simple example.
|
||||
// But in the real world, you might have multiple threads running in parallel,
|
||||
// and you might accidently modify a node while another thread is processing it.
|
||||
//
|
||||
// To completely fix this problem, and provide write-access thread-safety, would require extensive overhead.
|
||||
// This overhead is completely unwanted in the majority of cases.
|
||||
// Most XML usage patterns are heavily read-only.
|
||||
// And in the case of xml creation or modification, it is generally done on the same thread.
|
||||
// Thus the KissXML library is write-access thread-unsafe, but provides speedier performance.
|
||||
//
|
||||
// However, when such a bug does creep up, it produces horrible side-effects.
|
||||
// Essentially the pointer to the underlying xml structure becomes a dangling pointer,
|
||||
// which means that accessing the dangling pointer might give you the correct results, or completely random results.
|
||||
// And attempting to make modifications to non-existant xml nodes via the dangling pointer might do nothing,
|
||||
// or completely corrupt your heap and cause un-explainable crashes in random parts of your library.
|
||||
// Heap corruption is one of the worst problems to track down.
|
||||
// So to help out, the library provides a debugging macro to track down these problems.
|
||||
// That is, if you invalidate the write-access thread-unsafe rule,
|
||||
// this macro will tell you when you're trying to access a now-dangling pointer.
|
||||
//
|
||||
// How does it work?
|
||||
// Well everytime a DDXML wrapper object is created atop a libxml structure,
|
||||
// it marks the linkage in a table.
|
||||
// And everytime a libxml structure is freed, it destorys all corresponding linkages in the table.
|
||||
// So everytime a DDXML wrapper objects is about to dereference it's pointer,
|
||||
// it first ensures the linkage still exists in the table.
|
||||
//
|
||||
// Set to 1 to enable
|
||||
// Set to 0 to disable (this is the default)
|
||||
//
|
||||
// The debugging macro adds a significant amount of overhead, and should NOT be enabled on production builds.
|
||||
|
||||
#if DEBUG
|
||||
#define DDXML_DEBUG_MEMORY_ISSUES 0
|
||||
#else
|
||||
#define DDXML_DEBUG_MEMORY_ISSUES 0 // Don't change me!
|
||||
#endif
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DDXMLElement.h"
|
||||
#import "DDXMLNode.h"
|
||||
|
||||
/**
|
||||
* Welcome to KissXML.
|
||||
*
|
||||
* The project page has documentation if you have questions.
|
||||
* https://github.com/robbiehanson/KissXML
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/KissXML/wiki/GettingStarted
|
||||
*
|
||||
* KissXML provides a drop-in replacement for Apple's NSXML class cluster.
|
||||
* The goal is to get the exact same behavior as the NSXML classes.
|
||||
*
|
||||
* For API Reference, see Apple's excellent documentation,
|
||||
* either via Xcode's Mac OS X documentation, or via the web:
|
||||
*
|
||||
* https://github.com/robbiehanson/KissXML/wiki/Reference
|
||||
**/
|
||||
|
||||
enum {
|
||||
DDXMLDocumentXMLKind = 0,
|
||||
DDXMLDocumentXHTMLKind,
|
||||
DDXMLDocumentHTMLKind,
|
||||
DDXMLDocumentTextKind
|
||||
};
|
||||
typedef NSUInteger DDXMLDocumentContentKind;
|
||||
|
||||
@interface DDXMLDocument : DDXMLNode
|
||||
{
|
||||
}
|
||||
|
||||
- (id)initWithXMLString:(NSString *)string options:(NSUInteger)mask error:(NSError **)error;
|
||||
//- (id)initWithContentsOfURL:(NSURL *)url options:(NSUInteger)mask error:(NSError **)error;
|
||||
- (id)initWithData:(NSData *)data options:(NSUInteger)mask error:(NSError **)error;
|
||||
//- (id)initWithRootElement:(DDXMLElement *)element;
|
||||
|
||||
//+ (Class)replacementClassForClass:(Class)cls;
|
||||
|
||||
//- (void)setCharacterEncoding:(NSString *)encoding; //primitive
|
||||
//- (NSString *)characterEncoding; //primitive
|
||||
|
||||
//- (void)setVersion:(NSString *)version;
|
||||
//- (NSString *)version;
|
||||
|
||||
//- (void)setStandalone:(BOOL)standalone;
|
||||
//- (BOOL)isStandalone;
|
||||
|
||||
//- (void)setDocumentContentKind:(DDXMLDocumentContentKind)kind;
|
||||
//- (DDXMLDocumentContentKind)documentContentKind;
|
||||
|
||||
//- (void)setMIMEType:(NSString *)MIMEType;
|
||||
//- (NSString *)MIMEType;
|
||||
|
||||
//- (void)setDTD:(DDXMLDTD *)documentTypeDeclaration;
|
||||
//- (DDXMLDTD *)DTD;
|
||||
|
||||
//- (void)setRootElement:(DDXMLNode *)root;
|
||||
- (DDXMLElement *)rootElement;
|
||||
|
||||
//- (void)insertChild:(DDXMLNode *)child atIndex:(NSUInteger)index;
|
||||
|
||||
//- (void)insertChildren:(NSArray *)children atIndex:(NSUInteger)index;
|
||||
|
||||
//- (void)removeChildAtIndex:(NSUInteger)index;
|
||||
|
||||
//- (void)setChildren:(NSArray *)children;
|
||||
|
||||
//- (void)addChild:(DDXMLNode *)child;
|
||||
|
||||
//- (void)replaceChildAtIndex:(NSUInteger)index withNode:(DDXMLNode *)node;
|
||||
|
||||
- (NSData *)XMLData;
|
||||
- (NSData *)XMLDataWithOptions:(NSUInteger)options;
|
||||
|
||||
//- (id)objectByApplyingXSLT:(NSData *)xslt arguments:(NSDictionary *)arguments error:(NSError **)error;
|
||||
//- (id)objectByApplyingXSLTString:(NSString *)xslt arguments:(NSDictionary *)arguments error:(NSError **)error;
|
||||
//- (id)objectByApplyingXSLTAtURL:(NSURL *)xsltURL arguments:(NSDictionary *)argument error:(NSError **)error;
|
||||
|
||||
//- (BOOL)validateAndReturnError:(NSError **)error;
|
||||
|
||||
@end
|
||||
Vendored
+140
@@ -0,0 +1,140 @@
|
||||
#import "DDXMLPrivate.h"
|
||||
#import "NSString+DDXML.h"
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Welcome to KissXML.
|
||||
*
|
||||
* The project page has documentation if you have questions.
|
||||
* https://github.com/robbiehanson/KissXML
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/KissXML/wiki/GettingStarted
|
||||
*
|
||||
* KissXML provides a drop-in replacement for Apple's NSXML class cluster.
|
||||
* The goal is to get the exact same behavior as the NSXML classes.
|
||||
*
|
||||
* For API Reference, see Apple's excellent documentation,
|
||||
* either via Xcode's Mac OS X documentation, or via the web:
|
||||
*
|
||||
* https://github.com/robbiehanson/KissXML/wiki/Reference
|
||||
**/
|
||||
|
||||
@implementation DDXMLDocument
|
||||
|
||||
/**
|
||||
* Returns a DDXML wrapper object for the given primitive node.
|
||||
* The given node MUST be non-NULL and of the proper type.
|
||||
**/
|
||||
+ (id)nodeWithDocPrimitive:(xmlDocPtr)doc owner:(DDXMLNode *)owner
|
||||
{
|
||||
return [[DDXMLDocument alloc] initWithDocPrimitive:doc owner:owner];
|
||||
}
|
||||
|
||||
- (id)initWithDocPrimitive:(xmlDocPtr)doc owner:(DDXMLNode *)inOwner
|
||||
{
|
||||
self = [super initWithPrimitive:(xmlKindPtr)doc owner:inOwner];
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (id)nodeWithPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)owner
|
||||
{
|
||||
// Promote initializers which use proper parameter types to enable compiler to catch more mistakes
|
||||
NSAssert(NO, @"Use nodeWithDocPrimitive:owner:");
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)initWithPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)inOwner
|
||||
{
|
||||
// Promote initializers which use proper parameter types to enable compiler to catch more mistakes.
|
||||
NSAssert(NO, @"Use initWithDocPrimitive:owner:");
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and returns a DDXMLDocument object created from an NSData object.
|
||||
*
|
||||
* Returns an initialized DDXMLDocument object, or nil if initialization fails
|
||||
* because of parsing errors or other reasons.
|
||||
**/
|
||||
- (id)initWithXMLString:(NSString *)string options:(NSUInteger)mask error:(NSError **)error
|
||||
{
|
||||
return [self initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:mask
|
||||
error:error];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and returns a DDXMLDocument object created from an NSData object.
|
||||
*
|
||||
* Returns an initialized DDXMLDocument object, or nil if initialization fails
|
||||
* because of parsing errors or other reasons.
|
||||
**/
|
||||
- (id)initWithData:(NSData *)data options:(NSUInteger)mask error:(NSError **)error
|
||||
{
|
||||
if (data == nil || [data length] == 0)
|
||||
{
|
||||
if (error) *error = [NSError errorWithDomain:@"DDXMLErrorDomain" code:0 userInfo:nil];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Even though xmlKeepBlanksDefault(0) is called in DDXMLNode's initialize method,
|
||||
// it has been documented that this call seems to get reset on the iPhone:
|
||||
// http://code.google.com/p/kissxml/issues/detail?id=8
|
||||
//
|
||||
// Therefore, we call it again here just to be safe.
|
||||
xmlKeepBlanksDefault(0);
|
||||
|
||||
xmlDocPtr doc = xmlParseMemory([data bytes], (int)[data length]);
|
||||
if (doc == NULL)
|
||||
{
|
||||
if (error) *error = [NSError errorWithDomain:@"DDXMLErrorDomain" code:1 userInfo:nil];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [self initWithDocPrimitive:doc owner:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root element of the receiver.
|
||||
**/
|
||||
- (DDXMLElement *)rootElement
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
xmlDocPtr doc = (xmlDocPtr)genericPtr;
|
||||
|
||||
// doc->children is a list containing possibly comments, DTDs, etc...
|
||||
|
||||
xmlNodePtr rootNode = xmlDocGetRootElement(doc);
|
||||
|
||||
if (rootNode != NULL)
|
||||
return [DDXMLElement nodeWithElementPrimitive:rootNode owner:self];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSData *)XMLData
|
||||
{
|
||||
// Zombie test occurs in XMLString
|
||||
|
||||
return [[self XMLString] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSData *)XMLDataWithOptions:(NSUInteger)options
|
||||
{
|
||||
// Zombie test occurs in XMLString
|
||||
|
||||
return [[self XMLStringWithOptions:options] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@end
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DDXMLNode.h"
|
||||
|
||||
/**
|
||||
* Welcome to KissXML.
|
||||
*
|
||||
* The project page has documentation if you have questions.
|
||||
* https://github.com/robbiehanson/KissXML
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/KissXML/wiki/GettingStarted
|
||||
*
|
||||
* KissXML provides a drop-in replacement for Apple's NSXML class cluster.
|
||||
* The goal is to get the exact same behavior as the NSXML classes.
|
||||
*
|
||||
* For API Reference, see Apple's excellent documentation,
|
||||
* either via Xcode's Mac OS X documentation, or via the web:
|
||||
*
|
||||
* https://github.com/robbiehanson/KissXML/wiki/Reference
|
||||
**/
|
||||
|
||||
@interface DDXMLElement : DDXMLNode
|
||||
{
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)name;
|
||||
- (id)initWithName:(NSString *)name URI:(NSString *)URI;
|
||||
- (id)initWithName:(NSString *)name stringValue:(NSString *)string;
|
||||
- (id)initWithXMLString:(NSString *)string error:(NSError **)error;
|
||||
|
||||
#pragma mark --- Elements by name ---
|
||||
|
||||
- (NSArray *)elementsForName:(NSString *)name;
|
||||
- (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)URI;
|
||||
|
||||
#pragma mark --- Attributes ---
|
||||
|
||||
- (void)addAttribute:(DDXMLNode *)attribute;
|
||||
- (void)removeAttributeForName:(NSString *)name;
|
||||
- (void)setAttributes:(NSArray *)attributes;
|
||||
//- (void)setAttributesAsDictionary:(NSDictionary *)attributes;
|
||||
- (NSArray *)attributes;
|
||||
- (DDXMLNode *)attributeForName:(NSString *)name;
|
||||
//- (DDXMLNode *)attributeForLocalName:(NSString *)localName URI:(NSString *)URI;
|
||||
|
||||
#pragma mark --- Namespaces ---
|
||||
|
||||
- (void)addNamespace:(DDXMLNode *)aNamespace;
|
||||
- (void)removeNamespaceForPrefix:(NSString *)name;
|
||||
- (void)setNamespaces:(NSArray *)namespaces;
|
||||
- (NSArray *)namespaces;
|
||||
- (DDXMLNode *)namespaceForPrefix:(NSString *)prefix;
|
||||
- (DDXMLNode *)resolveNamespaceForName:(NSString *)name;
|
||||
- (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI;
|
||||
|
||||
#pragma mark --- Children ---
|
||||
|
||||
- (void)insertChild:(DDXMLNode *)child atIndex:(NSUInteger)index;
|
||||
//- (void)insertChildren:(NSArray *)children atIndex:(NSUInteger)index;
|
||||
- (void)removeChildAtIndex:(NSUInteger)index;
|
||||
- (void)setChildren:(NSArray *)children;
|
||||
- (void)addChild:(DDXMLNode *)child;
|
||||
//- (void)replaceChildAtIndex:(NSUInteger)index withNode:(DDXMLNode *)node;
|
||||
//- (void)normalizeAdjacentTextNodesPreservingCDATA:(BOOL)preserve;
|
||||
|
||||
@end
|
||||
Vendored
+801
@@ -0,0 +1,801 @@
|
||||
#import "DDXMLPrivate.h"
|
||||
#import "NSString+DDXML.h"
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Welcome to KissXML.
|
||||
*
|
||||
* The project page has documentation if you have questions.
|
||||
* https://github.com/robbiehanson/KissXML
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/KissXML/wiki/GettingStarted
|
||||
*
|
||||
* KissXML provides a drop-in replacement for Apple's NSXML class cluster.
|
||||
* The goal is to get the exact same behavior as the NSXML classes.
|
||||
*
|
||||
* For API Reference, see Apple's excellent documentation,
|
||||
* either via Xcode's Mac OS X documentation, or via the web:
|
||||
*
|
||||
* https://github.com/robbiehanson/KissXML/wiki/Reference
|
||||
**/
|
||||
|
||||
@implementation DDXMLElement
|
||||
|
||||
/**
|
||||
* Returns a DDXML wrapper object for the given primitive node.
|
||||
* The given node MUST be non-NULL and of the proper type.
|
||||
**/
|
||||
+ (id)nodeWithElementPrimitive:(xmlNodePtr)node owner:(DDXMLNode *)owner
|
||||
{
|
||||
return [[DDXMLElement alloc] initWithElementPrimitive:node owner:owner];
|
||||
}
|
||||
|
||||
- (id)initWithElementPrimitive:(xmlNodePtr)node owner:(DDXMLNode *)inOwner
|
||||
{
|
||||
self = [super initWithPrimitive:(xmlKindPtr)node owner:inOwner];
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (id)nodeWithPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)owner
|
||||
{
|
||||
// Promote initializers which use proper parameter types to enable compiler to catch more mistakes
|
||||
NSAssert(NO, @"Use nodeWithElementPrimitive:owner:");
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)initWithPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)inOwner
|
||||
{
|
||||
// Promote initializers which use proper parameter types to enable compiler to catch more mistakes.
|
||||
NSAssert(NO, @"Use initWithElementPrimitive:owner:");
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)name
|
||||
{
|
||||
// Note: Make every guarantee that genericPtr is not null
|
||||
|
||||
xmlNodePtr node = xmlNewNode(NULL, [name xmlChar]);
|
||||
if (node == NULL)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [self initWithElementPrimitive:node owner:nil];
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)name URI:(NSString *)URI
|
||||
{
|
||||
// Note: Make every guarantee that genericPtr is not null
|
||||
|
||||
xmlNodePtr node = xmlNewNode(NULL, [name xmlChar]);
|
||||
if (node == NULL)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
DDXMLElement *result = [self initWithElementPrimitive:node owner:nil];
|
||||
[result setURI:URI];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)name stringValue:(NSString *)string
|
||||
{
|
||||
// Note: Make every guarantee that genericPtr is not null
|
||||
|
||||
xmlNodePtr node = xmlNewNode(NULL, [name xmlChar]);
|
||||
if (node == NULL)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
DDXMLElement *result = [self initWithElementPrimitive:node owner:nil];
|
||||
[result setStringValue:string];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (id)initWithXMLString:(NSString *)string error:(NSError **)error
|
||||
{
|
||||
DDXMLDocument *doc = [[DDXMLDocument alloc] initWithXMLString:string options:0 error:error];
|
||||
if (doc == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
DDXMLElement *result = [doc rootElement];
|
||||
[result detach];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Elements by name
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Helper method elementsForName and elementsForLocalName:URI: so work isn't duplicated.
|
||||
* The name parameter is required, all others are optional.
|
||||
**/
|
||||
- (NSArray *)_elementsForName:(NSString *)name
|
||||
localName:(NSString *)localName
|
||||
prefix:(NSString *)prefix
|
||||
uri:(NSString *)uri
|
||||
{
|
||||
// This is a private/internal method
|
||||
|
||||
// Rule : !uri => match: name
|
||||
// Rule : uri && hasPrefix => match: name || (localName && uri)
|
||||
// Rule : uri && !hasPefix => match: name && uri
|
||||
|
||||
xmlNodePtr node = (xmlNodePtr)genericPtr;
|
||||
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
|
||||
BOOL hasPrefix = [prefix length] > 0;
|
||||
|
||||
const xmlChar *xmlName = [name xmlChar];
|
||||
const xmlChar *xmlLocalName = [localName xmlChar];
|
||||
const xmlChar *xmlUri = [uri xmlChar];
|
||||
|
||||
xmlNodePtr child = node->children;
|
||||
while (child)
|
||||
{
|
||||
if (IsXmlNodePtr(child))
|
||||
{
|
||||
BOOL match = NO;
|
||||
|
||||
if (uri == nil)
|
||||
{
|
||||
match = xmlStrEqual(child->name, xmlName);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL nameMatch = xmlStrEqual(child->name, xmlName);
|
||||
BOOL localNameMatch = xmlStrEqual(child->name, xmlLocalName);
|
||||
|
||||
BOOL uriMatch = NO;
|
||||
if (child->ns)
|
||||
{
|
||||
uriMatch = xmlStrEqual(child->ns->href, xmlUri);
|
||||
}
|
||||
|
||||
if (hasPrefix)
|
||||
match = nameMatch || (localNameMatch && uriMatch);
|
||||
else
|
||||
match = nameMatch && uriMatch;
|
||||
}
|
||||
|
||||
if (match)
|
||||
{
|
||||
[result addObject:[DDXMLElement nodeWithElementPrimitive:child owner:self]];
|
||||
}
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the child element nodes (as DDXMLElement objects) of the receiver that have a specified name.
|
||||
*
|
||||
* If name is a qualified name, then this method invokes elementsForLocalName:URI: with the URI parameter set to
|
||||
* the URI associated with the prefix. Otherwise comparison is based on string equality of the qualified or
|
||||
* non-qualified name.
|
||||
**/
|
||||
- (NSArray *)elementsForName:(NSString *)name
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
if (name == nil) return [NSArray array];
|
||||
|
||||
// We need to check to see if name has a prefix.
|
||||
// If it does have a prefix, we need to figure out what the corresponding URI is for that prefix,
|
||||
// and then search for any elements that have the same name (including prefix) OR have the same URI.
|
||||
// Otherwise we loop through the children as usual and do a string compare on the name
|
||||
|
||||
NSString *prefix;
|
||||
NSString *localName;
|
||||
|
||||
[DDXMLNode getPrefix:&prefix localName:&localName forName:name];
|
||||
|
||||
if ([prefix length] > 0)
|
||||
{
|
||||
xmlNodePtr node = (xmlNodePtr)genericPtr;
|
||||
|
||||
// Note: We use xmlSearchNs instead of resolveNamespaceForName: because
|
||||
// we want to avoid creating wrapper objects when possible.
|
||||
|
||||
xmlNsPtr ns = xmlSearchNs(node->doc, node, [prefix xmlChar]);
|
||||
if (ns)
|
||||
{
|
||||
NSString *uri = [NSString stringWithUTF8String:((const char *)ns->href)];
|
||||
return [self _elementsForName:name localName:localName prefix:prefix uri:uri];
|
||||
}
|
||||
}
|
||||
|
||||
return [self _elementsForName:name localName:localName prefix:prefix uri:nil];
|
||||
}
|
||||
|
||||
- (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)uri
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
if (localName == nil) return [NSArray array];
|
||||
|
||||
// We need to figure out what the prefix is for this URI.
|
||||
// Then we search for elements that are named prefix:localName OR (named localName AND have the given URI).
|
||||
|
||||
NSString *prefix = [self _recursiveResolvePrefixForURI:uri atNode:(xmlNodePtr)genericPtr];
|
||||
if (prefix)
|
||||
{
|
||||
NSString *name = [NSString stringWithFormat:@"%@:%@", prefix, localName];
|
||||
|
||||
return [self _elementsForName:name localName:localName prefix:prefix uri:uri];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *prefix;
|
||||
NSString *realLocalName;
|
||||
|
||||
[DDXMLNode getPrefix:&prefix localName:&realLocalName forName:localName];
|
||||
|
||||
return [self _elementsForName:localName localName:realLocalName prefix:prefix uri:uri];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Attributes
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (BOOL)_hasAttributeWithName:(NSString *)name
|
||||
{
|
||||
// This is a private/internal method
|
||||
|
||||
xmlAttrPtr attr = ((xmlNodePtr)genericPtr)->properties;
|
||||
if (attr)
|
||||
{
|
||||
const xmlChar *xmlName = [name xmlChar];
|
||||
do
|
||||
{
|
||||
if (xmlStrEqual(attr->name, xmlName))
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
attr = attr->next;
|
||||
|
||||
} while (attr);
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)_removeAttributeForName:(NSString *)name
|
||||
{
|
||||
// This is a private/internal method
|
||||
|
||||
xmlAttrPtr attr = ((xmlNodePtr)genericPtr)->properties;
|
||||
if (attr)
|
||||
{
|
||||
const xmlChar *xmlName = [name xmlChar];
|
||||
do
|
||||
{
|
||||
if (xmlStrEqual(attr->name, xmlName))
|
||||
{
|
||||
[DDXMLNode removeAttribute:attr];
|
||||
return;
|
||||
}
|
||||
attr = attr->next;
|
||||
|
||||
} while(attr);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addAttribute:(DDXMLNode *)attribute
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
// NSXML version uses this same assertion
|
||||
DDXMLAssert([attribute _hasParent] == NO, @"Cannot add an attribute with a parent; detach or copy first");
|
||||
DDXMLAssert(IsXmlAttrPtr(attribute->genericPtr), @"Not an attribute");
|
||||
|
||||
[self _removeAttributeForName:[attribute name]];
|
||||
|
||||
// xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
|
||||
// Add a new node to @parent, at the end of the child (or property) list merging
|
||||
// adjacent TEXT nodes (in which case @cur is freed). If the new node is ATTRIBUTE, it is added
|
||||
// into properties instead of children. If there is an attribute with equal name, it is first destroyed.
|
||||
|
||||
xmlAddChild((xmlNodePtr)genericPtr, (xmlNodePtr)attribute->genericPtr);
|
||||
|
||||
// The attribute is now part of the xml tree heirarchy
|
||||
attribute->owner = self;
|
||||
}
|
||||
|
||||
- (void)removeAttributeForName:(NSString *)name
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
[self _removeAttributeForName:name];
|
||||
}
|
||||
|
||||
- (NSArray *)attributes
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
|
||||
xmlAttrPtr attr = ((xmlNodePtr)genericPtr)->properties;
|
||||
while (attr != NULL)
|
||||
{
|
||||
[result addObject:[DDXMLAttributeNode nodeWithAttrPrimitive:attr owner:self]];
|
||||
|
||||
attr = attr->next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (DDXMLNode *)attributeForName:(NSString *)name
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
xmlAttrPtr attr = ((xmlNodePtr)genericPtr)->properties;
|
||||
if (attr)
|
||||
{
|
||||
const xmlChar *xmlName = [name xmlChar];
|
||||
do
|
||||
{
|
||||
if (attr->ns && attr->ns->prefix)
|
||||
{
|
||||
// If the attribute name was originally something like "xml:quack",
|
||||
// then attr->name is "quack" and attr->ns->prefix is "xml".
|
||||
//
|
||||
// So if the user is searching for "xml:quack" we need to take the prefix into account.
|
||||
// Note that "xml:quack" is what would be printed if we output the attribute.
|
||||
|
||||
if (xmlStrQEqual(attr->ns->prefix, attr->name, xmlName))
|
||||
{
|
||||
return [DDXMLAttributeNode nodeWithAttrPrimitive:attr owner:self];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmlStrEqual(attr->name, xmlName))
|
||||
{
|
||||
return [DDXMLAttributeNode nodeWithAttrPrimitive:attr owner:self];
|
||||
}
|
||||
}
|
||||
|
||||
attr = attr->next;
|
||||
|
||||
} while (attr);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of attributes for the element.
|
||||
* Any previously set attributes are removed.
|
||||
**/
|
||||
- (void)setAttributes:(NSArray *)attributes
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
[DDXMLNode removeAllAttributesFromNode:(xmlNodePtr)genericPtr];
|
||||
|
||||
NSUInteger i;
|
||||
for (i = 0; i < [attributes count]; i++)
|
||||
{
|
||||
DDXMLNode *attribute = [attributes objectAtIndex:i];
|
||||
[self addAttribute:attribute];
|
||||
|
||||
// Note: The addAttributes method properly sets the freeOnDealloc ivar.
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Namespaces
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)_removeNamespaceForPrefix:(NSString *)name
|
||||
{
|
||||
xmlNodePtr node = (xmlNodePtr)genericPtr;
|
||||
|
||||
// If name is nil or the empty string, the user is wishing to remove the default namespace
|
||||
const xmlChar *xmlName = [name length] > 0 ? [name xmlChar] : NULL;
|
||||
|
||||
xmlNsPtr ns = node->nsDef;
|
||||
while (ns != NULL)
|
||||
{
|
||||
if (xmlStrEqual(ns->prefix, xmlName))
|
||||
{
|
||||
[DDXMLNode removeNamespace:ns fromNode:node];
|
||||
break;
|
||||
}
|
||||
ns = ns->next;
|
||||
}
|
||||
|
||||
// Note: The removeNamespace method properly handles the situation where the namespace is the default namespace
|
||||
}
|
||||
|
||||
- (void)_addNamespace:(DDXMLNode *)namespace
|
||||
{
|
||||
// NSXML version uses this same assertion
|
||||
DDXMLAssert([namespace _hasParent] == NO, @"Cannot add a namespace with a parent; detach or copy first");
|
||||
DDXMLAssert(IsXmlNsPtr(namespace->genericPtr), @"Not a namespace");
|
||||
|
||||
xmlNodePtr node = (xmlNodePtr)genericPtr;
|
||||
xmlNsPtr ns = (xmlNsPtr)namespace->genericPtr;
|
||||
|
||||
// Beware: [namespace prefix] does NOT return what you might expect. Use [namespace name] instead.
|
||||
|
||||
NSString *namespaceName = [namespace name];
|
||||
|
||||
[self _removeNamespaceForPrefix:namespaceName];
|
||||
|
||||
xmlNsPtr currentNs = node->nsDef;
|
||||
if (currentNs == NULL)
|
||||
{
|
||||
node->nsDef = ns;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (currentNs->next != NULL)
|
||||
{
|
||||
currentNs = currentNs->next;
|
||||
}
|
||||
|
||||
currentNs->next = ns;
|
||||
}
|
||||
|
||||
// The namespace is now part of the xml tree heirarchy
|
||||
namespace->owner = self;
|
||||
|
||||
if ([namespace isKindOfClass:[DDXMLNamespaceNode class]])
|
||||
{
|
||||
DDXMLNamespaceNode *ddNamespace = (DDXMLNamespaceNode *)namespace;
|
||||
|
||||
// The xmlNs structure doesn't contain a reference to the parent, so we manage our own reference
|
||||
[ddNamespace _setNsParentPtr:node];
|
||||
}
|
||||
|
||||
// Did we just add a default namespace
|
||||
if ([namespaceName isEqualToString:@""])
|
||||
{
|
||||
node->ns = ns;
|
||||
|
||||
// Note: The removeNamespaceForPrefix method above properly handled removing any previous default namespace
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addNamespace:(DDXMLNode *)namespace
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
[self _addNamespace:namespace];
|
||||
}
|
||||
|
||||
- (void)removeNamespaceForPrefix:(NSString *)name
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
[self _removeNamespaceForPrefix:name];
|
||||
}
|
||||
|
||||
- (NSArray *)namespaces
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
|
||||
xmlNsPtr ns = ((xmlNodePtr)genericPtr)->nsDef;
|
||||
while (ns != NULL)
|
||||
{
|
||||
[result addObject:[DDXMLNamespaceNode nodeWithNsPrimitive:ns nsParent:(xmlNodePtr)genericPtr owner:self]];
|
||||
|
||||
ns = ns->next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (DDXMLNode *)namespaceForPrefix:(NSString *)prefix
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
// If the prefix is nil or the empty string, the user is requesting the default namespace
|
||||
|
||||
if ([prefix length] == 0)
|
||||
{
|
||||
// Requesting the default namespace
|
||||
xmlNsPtr ns = ((xmlNodePtr)genericPtr)->ns;
|
||||
if (ns != NULL)
|
||||
{
|
||||
return [DDXMLNamespaceNode nodeWithNsPrimitive:ns nsParent:(xmlNodePtr)genericPtr owner:self];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlNsPtr ns = ((xmlNodePtr)genericPtr)->nsDef;
|
||||
if (ns)
|
||||
{
|
||||
const xmlChar *xmlPrefix = [prefix xmlChar];
|
||||
do
|
||||
{
|
||||
if (xmlStrEqual(ns->prefix, xmlPrefix))
|
||||
{
|
||||
return [DDXMLNamespaceNode nodeWithNsPrimitive:ns nsParent:(xmlNodePtr)genericPtr owner:self];
|
||||
}
|
||||
ns = ns->next;
|
||||
|
||||
} while (ns);
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setNamespaces:(NSArray *)namespaces
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
[DDXMLNode removeAllNamespacesFromNode:(xmlNodePtr)genericPtr];
|
||||
|
||||
NSUInteger i;
|
||||
for (i = 0; i < [namespaces count]; i++)
|
||||
{
|
||||
DDXMLNode *namespace = [namespaces objectAtIndex:i];
|
||||
[self _addNamespace:namespace];
|
||||
|
||||
// Note: The addNamespace method properly sets the freeOnDealloc ivar.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively searches the given node for the given namespace
|
||||
**/
|
||||
- (DDXMLNode *)_recursiveResolveNamespaceForPrefix:(NSString *)prefix atNode:(xmlNodePtr)nodePtr
|
||||
{
|
||||
// This is a private/internal method
|
||||
|
||||
if (nodePtr == NULL) return nil;
|
||||
|
||||
xmlNsPtr ns = nodePtr->nsDef;
|
||||
if (ns)
|
||||
{
|
||||
const xmlChar *xmlPrefix = [prefix xmlChar];
|
||||
do
|
||||
{
|
||||
if (xmlStrEqual(ns->prefix, xmlPrefix))
|
||||
{
|
||||
return [DDXMLNamespaceNode nodeWithNsPrimitive:ns nsParent:nodePtr owner:self];
|
||||
}
|
||||
ns = ns->next;
|
||||
|
||||
} while(ns);
|
||||
}
|
||||
|
||||
return [self _recursiveResolveNamespaceForPrefix:prefix atNode:nodePtr->parent];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the namespace node with the prefix matching the given qualified name.
|
||||
* Eg: You pass it "a:dog", it returns the namespace (defined in this node or parent nodes) that has the "a" prefix.
|
||||
**/
|
||||
- (DDXMLNode *)resolveNamespaceForName:(NSString *)name
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
// If the user passes nil or an empty string for name, they're looking for the default namespace.
|
||||
if ([name length] == 0)
|
||||
{
|
||||
return [self _recursiveResolveNamespaceForPrefix:nil atNode:(xmlNodePtr)genericPtr];
|
||||
}
|
||||
|
||||
NSString *prefix = [[self class] prefixForName:name];
|
||||
|
||||
if ([prefix length] > 0)
|
||||
{
|
||||
// Unfortunately we can't use xmlSearchNs because it returns an xmlNsPtr.
|
||||
// This gives us mostly what we want, except we also need to know the nsParent.
|
||||
// So we do the recursive search ourselves.
|
||||
|
||||
return [self _recursiveResolveNamespaceForPrefix:prefix atNode:(xmlNodePtr)genericPtr];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively searches the given node for a namespace with the given URI, and a set prefix.
|
||||
**/
|
||||
- (NSString *)_recursiveResolvePrefixForURI:(NSString *)uri atNode:(xmlNodePtr)nodePtr
|
||||
{
|
||||
// This is a private/internal method
|
||||
|
||||
if (nodePtr == NULL) return nil;
|
||||
|
||||
xmlNsPtr ns = nodePtr->nsDef;
|
||||
if (ns)
|
||||
{
|
||||
const xmlChar *xmlUri = [uri xmlChar];
|
||||
do
|
||||
{
|
||||
if (xmlStrEqual(ns->href, xmlUri))
|
||||
{
|
||||
if (ns->prefix != NULL)
|
||||
{
|
||||
return [NSString stringWithUTF8String:((const char *)ns->prefix)];
|
||||
}
|
||||
}
|
||||
ns = ns->next;
|
||||
|
||||
} while (ns);
|
||||
}
|
||||
|
||||
return [self _recursiveResolvePrefixForURI:uri atNode:nodePtr->parent];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix associated with the specified URI.
|
||||
* Returns a string that is the matching prefix or nil if it finds no matching prefix.
|
||||
**/
|
||||
- (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
// We can't use xmlSearchNsByHref because it will return xmlNsPtr's with NULL prefixes.
|
||||
// We're looking for a definitive prefix for the given URI.
|
||||
|
||||
return [self _recursiveResolvePrefixForURI:namespaceURI atNode:(xmlNodePtr)genericPtr];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Children
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)addChild:(DDXMLNode *)child
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
// NSXML version uses these same assertions
|
||||
DDXMLAssert([child _hasParent] == NO, @"Cannot add a child that has a parent; detach or copy first");
|
||||
DDXMLAssert(IsXmlNodePtr(child->genericPtr),
|
||||
@"Elements can only have text, elements, processing instructions, and comments as children");
|
||||
|
||||
xmlAddChild((xmlNodePtr)genericPtr, (xmlNodePtr)child->genericPtr);
|
||||
|
||||
// The node is now part of the xml tree heirarchy
|
||||
child->owner = self;
|
||||
}
|
||||
|
||||
- (void)insertChild:(DDXMLNode *)child atIndex:(NSUInteger)index
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
// NSXML version uses these same assertions
|
||||
DDXMLAssert([child _hasParent] == NO, @"Cannot add a child that has a parent; detach or copy first");
|
||||
DDXMLAssert(IsXmlNodePtr(child->genericPtr),
|
||||
@"Elements can only have text, elements, processing instructions, and comments as children");
|
||||
|
||||
NSUInteger i = 0;
|
||||
|
||||
xmlNodePtr childNodePtr = ((xmlNodePtr)genericPtr)->children;
|
||||
while (childNodePtr != NULL)
|
||||
{
|
||||
// Ignore all but element, comment, text, or processing instruction nodes
|
||||
if (IsXmlNodePtr(childNodePtr))
|
||||
{
|
||||
if (i == index)
|
||||
{
|
||||
xmlAddPrevSibling(childNodePtr, (xmlNodePtr)child->genericPtr);
|
||||
|
||||
child->owner = self;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
childNodePtr = childNodePtr->next;
|
||||
}
|
||||
|
||||
if (i == index)
|
||||
{
|
||||
xmlAddChild((xmlNodePtr)genericPtr, (xmlNodePtr)child->genericPtr);
|
||||
|
||||
child->owner = self;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// NSXML version uses this same assertion
|
||||
DDXMLAssert(NO, @"index (%u) beyond bounds (%u)", (unsigned)index, (unsigned)++i);
|
||||
}
|
||||
|
||||
- (void)removeChildAtIndex:(NSUInteger)index
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
NSUInteger i = 0;
|
||||
|
||||
xmlNodePtr child = ((xmlNodePtr)genericPtr)->children;
|
||||
while (child != NULL)
|
||||
{
|
||||
// Ignore all but element, comment, text, or processing instruction nodes
|
||||
if (IsXmlNodePtr(child))
|
||||
{
|
||||
if (i == index)
|
||||
{
|
||||
[DDXMLNode removeChild:child];
|
||||
return;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray *)children
|
||||
{
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
DDXMLNotZombieAssert();
|
||||
#endif
|
||||
|
||||
[DDXMLNode removeAllChildrenFromNode:(xmlNodePtr)genericPtr];
|
||||
|
||||
NSUInteger i;
|
||||
for (i = 0; i < [children count]; i++)
|
||||
{
|
||||
DDXMLNode *child = [children objectAtIndex:i];
|
||||
[self addChild:child];
|
||||
|
||||
// Note: The addChild method properly sets the freeOnDealloc ivar.
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Vendored
+161
@@ -0,0 +1,161 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !(TARGET_IPHONE_SIMULATOR)
|
||||
@import libxml;
|
||||
#else
|
||||
@import libxmlSimu;
|
||||
#endif
|
||||
|
||||
@class DDXMLDocument;
|
||||
|
||||
/**
|
||||
* Welcome to KissXML.
|
||||
*
|
||||
* The project page has documentation if you have questions.
|
||||
* https://github.com/robbiehanson/KissXML
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/KissXML/wiki/GettingStarted
|
||||
*
|
||||
* KissXML provides a drop-in replacement for Apple's NSXML class cluster.
|
||||
* The goal is to get the exact same behavior as the NSXML classes.
|
||||
*
|
||||
* For API Reference, see Apple's excellent documentation,
|
||||
* either via Xcode's Mac OS X documentation, or via the web:
|
||||
*
|
||||
* https://github.com/robbiehanson/KissXML/wiki/Reference
|
||||
**/
|
||||
|
||||
enum {
|
||||
DDXMLInvalidKind = 0,
|
||||
DDXMLDocumentKind = XML_DOCUMENT_NODE,
|
||||
DDXMLElementKind = XML_ELEMENT_NODE,
|
||||
DDXMLAttributeKind = XML_ATTRIBUTE_NODE,
|
||||
DDXMLNamespaceKind = XML_NAMESPACE_DECL,
|
||||
DDXMLProcessingInstructionKind = XML_PI_NODE,
|
||||
DDXMLCommentKind = XML_COMMENT_NODE,
|
||||
DDXMLTextKind = XML_TEXT_NODE,
|
||||
DDXMLDTDKind = XML_DTD_NODE,
|
||||
DDXMLEntityDeclarationKind = XML_ENTITY_DECL,
|
||||
DDXMLAttributeDeclarationKind = XML_ATTRIBUTE_DECL,
|
||||
DDXMLElementDeclarationKind = XML_ELEMENT_DECL,
|
||||
DDXMLNotationDeclarationKind = XML_NOTATION_NODE
|
||||
};
|
||||
typedef NSUInteger DDXMLNodeKind;
|
||||
|
||||
enum {
|
||||
DDXMLNodeOptionsNone = 0,
|
||||
DDXMLNodeExpandEmptyElement = 1 << 1,
|
||||
DDXMLNodeCompactEmptyElement = 1 << 2,
|
||||
DDXMLNodePrettyPrint = 1 << 17,
|
||||
};
|
||||
|
||||
|
||||
//extern struct _xmlKind;
|
||||
|
||||
|
||||
@interface DDXMLNode : NSObject <NSCopying>
|
||||
{
|
||||
// Every DDXML object is simply a wrapper around an underlying libxml node
|
||||
struct _xmlKind *genericPtr;
|
||||
|
||||
// Every libxml node resides somewhere within an xml tree heirarchy.
|
||||
// We cannot free the tree heirarchy until all referencing nodes have been released.
|
||||
// So all nodes retain a reference to the node that created them,
|
||||
// and when the last reference is released the tree gets freed.
|
||||
DDXMLNode *owner;
|
||||
}
|
||||
|
||||
//- (id)initWithKind:(DDXMLNodeKind)kind;
|
||||
|
||||
//- (id)initWithKind:(DDXMLNodeKind)kind options:(NSUInteger)options;
|
||||
|
||||
//+ (id)document;
|
||||
|
||||
//+ (id)documentWithRootElement:(DDXMLElement *)element;
|
||||
|
||||
+ (id)elementWithName:(NSString *)name;
|
||||
|
||||
+ (id)elementWithName:(NSString *)name URI:(NSString *)URI;
|
||||
|
||||
+ (id)elementWithName:(NSString *)name stringValue:(NSString *)string;
|
||||
|
||||
+ (id)elementWithName:(NSString *)name children:(NSArray *)children attributes:(NSArray *)attributes;
|
||||
|
||||
+ (id)attributeWithName:(NSString *)name stringValue:(NSString *)stringValue;
|
||||
|
||||
+ (id)attributeWithName:(NSString *)name URI:(NSString *)URI stringValue:(NSString *)stringValue;
|
||||
|
||||
+ (id)namespaceWithName:(NSString *)name stringValue:(NSString *)stringValue;
|
||||
|
||||
+ (id)processingInstructionWithName:(NSString *)name stringValue:(NSString *)stringValue;
|
||||
|
||||
+ (id)commentWithStringValue:(NSString *)stringValue;
|
||||
|
||||
+ (id)textWithStringValue:(NSString *)stringValue;
|
||||
|
||||
//+ (id)DTDNodeWithXMLString:(NSString *)string;
|
||||
|
||||
#pragma mark --- Properties ---
|
||||
|
||||
- (DDXMLNodeKind)kind;
|
||||
|
||||
- (void)setName:(NSString *)name;
|
||||
- (NSString *)name;
|
||||
|
||||
//- (void)setObjectValue:(id)value;
|
||||
//- (id)objectValue;
|
||||
|
||||
- (void)setStringValue:(NSString *)string;
|
||||
//- (void)setStringValue:(NSString *)string resolvingEntities:(BOOL)resolve;
|
||||
- (NSString *)stringValue;
|
||||
|
||||
#pragma mark --- Tree Navigation ---
|
||||
|
||||
- (NSUInteger)index;
|
||||
|
||||
- (NSUInteger)level;
|
||||
|
||||
- (DDXMLDocument *)rootDocument;
|
||||
|
||||
- (DDXMLNode *)parent;
|
||||
- (NSUInteger)childCount;
|
||||
- (NSArray *)children;
|
||||
- (DDXMLNode *)childAtIndex:(NSUInteger)index;
|
||||
|
||||
- (DDXMLNode *)previousSibling;
|
||||
- (DDXMLNode *)nextSibling;
|
||||
|
||||
- (DDXMLNode *)previousNode;
|
||||
- (DDXMLNode *)nextNode;
|
||||
|
||||
- (void)detach;
|
||||
|
||||
- (NSString *)XPath;
|
||||
|
||||
#pragma mark --- QNames ---
|
||||
|
||||
- (NSString *)localName;
|
||||
- (NSString *)prefix;
|
||||
|
||||
- (void)setURI:(NSString *)URI;
|
||||
- (NSString *)URI;
|
||||
|
||||
+ (NSString *)localNameForName:(NSString *)name;
|
||||
+ (NSString *)prefixForName:(NSString *)name;
|
||||
//+ (DDXMLNode *)predefinedNamespaceForPrefix:(NSString *)name;
|
||||
|
||||
#pragma mark --- Output ---
|
||||
|
||||
- (NSString *)description;
|
||||
- (NSString *)XMLString;
|
||||
- (NSString *)XMLStringWithOptions:(NSUInteger)options;
|
||||
//- (NSString *)canonicalXMLStringPreservingComments:(BOOL)comments;
|
||||
|
||||
#pragma mark --- XPath/XQuery ---
|
||||
|
||||
- (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error;
|
||||
//- (NSArray *)objectsForXQuery:(NSString *)xquery constants:(NSDictionary *)constants error:(NSError **)error;
|
||||
//- (NSArray *)objectsForXQuery:(NSString *)xquery error:(NSError **)error;
|
||||
|
||||
@end
|
||||
Vendored
+2905
File diff suppressed because it is too large.
Load diff
+229
@@ -0,0 +1,229 @@
|
||||
#import "DDXML.h"
|
||||
|
||||
|
||||
// We can't rely solely on NSAssert, because many developers disable them for release builds.
|
||||
// Our API contract requires us to keep these assertions intact.
|
||||
#define DDXMLAssert(condition, desc, ...) \
|
||||
do{ \
|
||||
if(!(condition)) { \
|
||||
[[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
|
||||
object:self \
|
||||
file:[NSString stringWithUTF8String:__FILE__] \
|
||||
lineNumber:__LINE__ \
|
||||
description:(desc), ##__VA_ARGS__]; \
|
||||
} \
|
||||
}while(NO)
|
||||
|
||||
|
||||
// Create assertion to ensure xml node is not a zombie.
|
||||
#if DDXML_DEBUG_MEMORY_ISSUES
|
||||
#define DDXMLNotZombieAssert() \
|
||||
do{ \
|
||||
if(DDXMLIsZombie(genericPtr, self)) { \
|
||||
NSString *desc = @"XML node is a zombie - It's parent structure has been freed!"; \
|
||||
[[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
|
||||
object:self \
|
||||
file:[NSString stringWithUTF8String:__FILE__] \
|
||||
lineNumber:__LINE__ \
|
||||
description:desc]; \
|
||||
} \
|
||||
}while(NO)
|
||||
#endif
|
||||
|
||||
#define DDLastErrorKey @"DDXML:LastError"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* DDXMLNode can represent several underlying types, such as xmlNodePtr, xmlDocPtr, xmlAttrPtr, xmlNsPtr, etc.
|
||||
* All of these are pointers to structures, and all of those structures start with a pointer, and a type.
|
||||
* The xmlKind struct is used as a generic structure, and a stepping stone.
|
||||
* We use it to check the type of a structure, and then perform the appropriate cast.
|
||||
*
|
||||
* For example:
|
||||
* if(genericPtr->type == XML_ATTRIBUTE_NODE)
|
||||
* {
|
||||
* xmlAttrPtr attr = (xmlAttrPtr)genericPtr;
|
||||
* // Do something with attr
|
||||
* }
|
||||
**/
|
||||
struct _xmlKind {
|
||||
void * ignore;
|
||||
xmlElementType type;
|
||||
};
|
||||
typedef struct _xmlKind *xmlKindPtr;
|
||||
|
||||
/**
|
||||
* Most xml types all start with this standard structure. In fact, all do except the xmlNsPtr.
|
||||
* We will occasionally take advantage of this to simplify code when the code wouldn't vary from type to type.
|
||||
* Obviously, you cannnot cast a xmlNsPtr to a xmlStdPtr.
|
||||
**/
|
||||
struct _xmlStd {
|
||||
void * _private;
|
||||
xmlElementType type;
|
||||
const xmlChar *name;
|
||||
struct _xmlNode *children;
|
||||
struct _xmlNode *last;
|
||||
struct _xmlNode *parent;
|
||||
struct _xmlStd *next;
|
||||
struct _xmlStd *prev;
|
||||
struct _xmlDoc *doc;
|
||||
};
|
||||
typedef struct _xmlStd *xmlStdPtr;
|
||||
|
||||
|
||||
NS_INLINE BOOL IsXmlAttrPtr(void *kindPtr)
|
||||
{
|
||||
return ((xmlKindPtr)kindPtr)->type == XML_ATTRIBUTE_NODE;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL IsXmlNodePtr(void *kindPtr)
|
||||
{
|
||||
switch (((xmlKindPtr)kindPtr)->type)
|
||||
{
|
||||
case XML_ELEMENT_NODE :
|
||||
case XML_PI_NODE :
|
||||
case XML_COMMENT_NODE :
|
||||
case XML_TEXT_NODE :
|
||||
case XML_CDATA_SECTION_NODE : return YES;
|
||||
default : return NO;
|
||||
}
|
||||
}
|
||||
|
||||
NS_INLINE BOOL IsXmlDocPtr(void *kindPtr)
|
||||
{
|
||||
return ((xmlKindPtr)kindPtr)->type == XML_DOCUMENT_NODE;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL IsXmlDtdPtr(void *kindPtr)
|
||||
{
|
||||
return ((xmlKindPtr)kindPtr)->type == XML_DTD_NODE;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL IsXmlNsPtr(void *kindPtr)
|
||||
{
|
||||
return ((xmlKindPtr)kindPtr)->type == XML_NAMESPACE_DECL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDXMLNamespaceNode : DDXMLNode
|
||||
{
|
||||
// The xmlNsPtr type doesn't store a reference to it's parent.
|
||||
// This is here to fix the problem, and make this class more compatible with the NSXML classes.
|
||||
xmlNodePtr nsParentPtr;
|
||||
}
|
||||
|
||||
+ (id)nodeWithNsPrimitive:(xmlNsPtr)ns nsParent:(xmlNodePtr)parent owner:(DDXMLNode *)owner;
|
||||
- (id)initWithNsPrimitive:(xmlNsPtr)ns nsParent:(xmlNodePtr)parent owner:(DDXMLNode *)owner;
|
||||
|
||||
- (xmlNodePtr)_nsParentPtr;
|
||||
- (void)_setNsParentPtr:(xmlNodePtr)parentPtr;
|
||||
|
||||
// Overrides several methods in DDXMLNode
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDXMLAttributeNode : DDXMLNode
|
||||
{
|
||||
// The xmlAttrPtr type doesn't allow for ownership of a namespace.
|
||||
//
|
||||
// In other types, such as xmlNodePtr:
|
||||
// - nsDef stores namespaces that are owned by the node (have been alloced by the node).
|
||||
// - ns is simply a pointer to the default namespace of the node, which may or may not reside in its own nsDef list.
|
||||
//
|
||||
// The xmlAttrPtr only has a ns, it doesn't have a nsDef list.
|
||||
// Which completely makes sense really, since namespaces have to be defined elsewhere.
|
||||
//
|
||||
// This is here to maintain compatibility with the NSXML classes,
|
||||
// where one can assign a namespace to an attribute independently.
|
||||
xmlNsPtr attrNsPtr;
|
||||
}
|
||||
|
||||
+ (id)nodeWithAttrPrimitive:(xmlAttrPtr)attr owner:(DDXMLNode *)owner;
|
||||
- (id)initWithAttrPrimitive:(xmlAttrPtr)attr owner:(DDXMLNode *)owner;
|
||||
|
||||
// Overrides several methods in DDXMLNode
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDXMLInvalidNode : DDXMLNode
|
||||
{
|
||||
}
|
||||
|
||||
// Overrides several methods in DDXMLNode
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDXMLNode (PrivateAPI)
|
||||
|
||||
+ (id)nodeWithUnknownPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)owner;
|
||||
|
||||
+ (id)nodeWithPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)owner;
|
||||
- (id)initWithPrimitive:(xmlKindPtr)kindPtr owner:(DDXMLNode *)owner;
|
||||
|
||||
- (BOOL)_hasParent;
|
||||
|
||||
+ (void)getHasPrefix:(BOOL *)hasPrefixPtr localName:(NSString **)localNamePtr forName:(NSString *)name;
|
||||
+ (void)getPrefix:(NSString **)prefixPtr localName:(NSString **)localNamePtr forName:(NSString *)name;
|
||||
|
||||
+ (void)recursiveStripDocPointersFromNode:(xmlNodePtr)node;
|
||||
|
||||
+ (void)detachNamespace:(xmlNsPtr)ns fromNode:(xmlNodePtr)node;
|
||||
+ (void)removeNamespace:(xmlNsPtr)ns fromNode:(xmlNodePtr)node;
|
||||
+ (void)removeAllNamespacesFromNode:(xmlNodePtr)node;
|
||||
|
||||
+ (void)detachAttribute:(xmlAttrPtr)attr andClean:(BOOL)clean;
|
||||
+ (void)detachAttribute:(xmlAttrPtr)attr;
|
||||
+ (void)removeAttribute:(xmlAttrPtr)attr;
|
||||
+ (void)removeAllAttributesFromNode:(xmlNodePtr)node;
|
||||
|
||||
+ (void)detachChild:(xmlNodePtr)child andClean:(BOOL)clean andFixNamespaces:(BOOL)fixNamespaces;
|
||||
+ (void)detachChild:(xmlNodePtr)child;
|
||||
+ (void)removeChild:(xmlNodePtr)child;
|
||||
+ (void)removeAllChildrenFromNode:(xmlNodePtr)node;
|
||||
|
||||
BOOL DDXMLIsZombie(void *xmlPtr, DDXMLNode *wrapper);
|
||||
|
||||
+ (NSError *)lastError;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDXMLElement (PrivateAPI)
|
||||
|
||||
+ (id)nodeWithElementPrimitive:(xmlNodePtr)node owner:(DDXMLNode *)owner;
|
||||
- (id)initWithElementPrimitive:(xmlNodePtr)node owner:(DDXMLNode *)owner;
|
||||
|
||||
- (DDXMLNode *)_recursiveResolveNamespaceForPrefix:(NSString *)prefix atNode:(xmlNodePtr)nodePtr;
|
||||
- (NSString *)_recursiveResolvePrefixForURI:(NSString *)uri atNode:(xmlNodePtr)nodePtr;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDXMLDocument (PrivateAPI)
|
||||
|
||||
+ (id)nodeWithDocPrimitive:(xmlDocPtr)doc owner:(DDXMLNode *)owner;
|
||||
- (id)initWithDocPrimitive:(xmlDocPtr)doc owner:(DDXMLNode *)owner;
|
||||
|
||||
@end
|
||||
Reference in new issue
Block a user