* Source/NSXMLDocument.m: Correct memory management.

* Source/NSXMLElement.m,
* Source/NSXMLNode.m: Add partial support for namespaces.
Try to bracket more libxml2 functions with version checks.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34967 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2012-03-21 09:01:48 +00:00
parent b5181106dd
commit 6bb7c00782
4 changed files with 383 additions and 100 deletions

View file

@ -1,3 +1,10 @@
2012-03-21 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSXMLDocument.m: Correct memory management.
* Source/NSXMLElement.m,
* Source/NSXMLNode.m: Add partial support for namespaces.
Try to bracket more libxml2 functions with version checks.
2012-03-21 Richard Frith-Macdonald <rfm@gnu.org> 2012-03-21 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSXMLDocument.m: * Source/NSXMLDocument.m:

View file

@ -220,6 +220,10 @@ GS_PRIVATE_INTERNAL(NSXMLDocument)
- (void) setCharacterEncoding: (NSString*)encoding - (void) setCharacterEncoding: (NSString*)encoding
{ {
if (internal->node->encoding != NULL)
{
xmlFree((xmlChar *)internal->node->encoding);
}
internal->node->encoding = XMLStringCopy(encoding); internal->node->encoding = XMLStringCopy(encoding);
} }
@ -264,6 +268,7 @@ GS_PRIVATE_INTERNAL(NSXMLDocument)
// remove all sub nodes // remove all sub nodes
[self setChildren: nil]; [self setChildren: nil];
// FIXME: Should we use addChild: here?
xmlDocSetRootElement(internal->node, [root _node]); xmlDocSetRootElement(internal->node, [root _node]);
// Do our subNode housekeeping... // Do our subNode housekeeping...
@ -279,8 +284,12 @@ GS_PRIVATE_INTERNAL(NSXMLDocument)
{ {
if ([version isEqualToString: @"1.0"] || [version isEqualToString: @"1.1"]) if ([version isEqualToString: @"1.0"] || [version isEqualToString: @"1.1"])
{ {
if (internal->node->version != NULL)
{
xmlFree((xmlChar *)internal->node->version);
}
internal->node->version = XMLStringCopy(version); internal->node->version = XMLStringCopy(version);
} }
else else
{ {
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException

View file

@ -37,15 +37,23 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
- (void) dealloc - (void) dealloc
{ {
/*
if (GS_EXISTS_INTERNAL && _internal != nil) if (GS_EXISTS_INTERNAL && _internal != nil)
{ {
while ([self childCount] > 0) /*
{ NSArray *subNodes = [internal->subNodes copy];
[self removeChildAtIndex: [self childCount] - 1]; NSEnumerator *enumerator = [subNodes objectEnumerator];
} NSXMLNode *subNode;
while ((subNode = [enumerator nextObject]) != nil)
{
if ([subNode kind] == NSXMLNamespaceKind)
{
[self removeNamespaceForPrefix: [subNode name]];
}
}
*/
} }
*/
[super dealloc]; [super dealloc];
} }
@ -132,33 +140,81 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
- (NSArray*) elementsForName: (NSString*)name - (NSArray*) elementsForName: (NSString*)name
{ {
NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10]; NSString *prefix = [[self class] prefixForName: name];
xmlNodePtr cur = NULL;
for (cur = internal->node->children; cur != NULL; cur = cur->next) if (nil != prefix)
{ {
NSString *n = StringFromXMLStringPtr(cur->name); NSXMLNode *ns = [self namespaceForPrefix: prefix];
if ([n isEqualToString: name])
{ if (nil != ns)
NSXMLNode *node = [NSXMLNode _objectForNode: cur]; {
[results addObject: node]; NSString *localName = [[self class] localNameForName: name];
}
// Namespace nodes have the URI as their stringValue
return [self elementsForLocalName: localName URI: [ns stringValue]];
}
} }
{
NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10];
xmlNodePtr cur = NULL;
for (cur = internal->node->children; cur != NULL; cur = cur->next)
{
if (cur->type == XML_ELEMENT_NODE)
{
NSString *n = StringFromXMLStringPtr(cur->name);
if ([n isEqualToString: name])
{
NSXMLNode *node = [NSXMLNode _objectForNode: cur];
[results addObject: node];
}
}
}
return results; return results;
}
} }
- (NSArray*) elementsForLocalName: (NSString*)localName URI: (NSString*)URI - (NSArray*) elementsForLocalName: (NSString*)localName URI: (NSString*)URI
{ {
[self notImplemented: _cmd]; NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10];
return nil; xmlNodePtr cur = NULL;
const xmlChar *href = XMLSTRING(URI);
xmlNsPtr parentNS = xmlSearchNsByHref(internal->node->doc, internal->node, href);
for (cur = internal->node->children; cur != NULL; cur = cur->next)
{
if (cur->type == XML_ELEMENT_NODE)
{
xmlNsPtr childNS = parentNS;
if (cur->nsDef != NULL)
{
childNS = xmlSearchNsByHref(internal->node->doc, cur, href);
}
if (cur->ns == childNS)
{
NSString *n = StringFromXMLStringPtr(cur->name);
if ([n isEqualToString: localName])
{
NSXMLNode *node = [NSXMLNode _objectForNode: cur];
[results addObject: node];
}
}
}
}
return results;
} }
- (void) addAttribute: (NSXMLNode*)attribute - (void) addAttribute: (NSXMLNode*)attribute
{ {
xmlNodePtr node = internal->node; xmlNodePtr node = internal->node;
xmlAttrPtr attr = (xmlAttrPtr)[attribute _node]; xmlAttrPtr attr = (xmlAttrPtr)[attribute _node];
xmlAttrPtr oldAttr = xmlHasProp(node, attr->name); xmlAttrPtr oldAttr;
if (nil != [attribute parent]) if (nil != [attribute parent])
{ {
@ -166,6 +222,27 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
format: @"Tried to add attribute to multiple parents."]; format: @"Tried to add attribute to multiple parents."];
} }
if (attr->ns != NULL)
{
xmlNsPtr ns = attr->ns;
if (ns->href == NULL)
{
xmlNsPtr newNs = xmlSearchNs(node->doc, node, ns->prefix);
if (newNs != NULL)
{
ns = newNs;
}
}
oldAttr = xmlHasNsProp(node, attr->name, ns->href);
}
else
{
oldAttr = xmlHasProp(node, attr->name);
}
if (NULL != oldAttr) if (NULL != oldAttr)
{ {
/* /*
@ -252,36 +329,65 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
- (NSXMLNode*) attributeForName: (NSString*)name - (NSXMLNode*) attributeForName: (NSString*)name
{ {
NSXMLNode *result = nil; NSString *prefix = [[self class] prefixForName: name];
xmlNodePtr node = internal->node;
xmlAttrPtr attributeNode = xmlHasProp(node, XMLSTRING(name));
if (NULL != attributeNode) if (nil != prefix)
{ {
result = [NSXMLNode _objectForNode: (xmlNodePtr)attributeNode]; NSXMLNode *ns = [self namespaceForPrefix: prefix];
if (nil != ns)
{
NSString *localName = [[self class] localNameForName: name];
// Namespace nodes have the URI as their stringValue
return [self attributeForLocalName: localName URI: [ns stringValue]];
}
} }
return result; {
NSXMLNode *result = nil;
xmlNodePtr node = internal->node;
xmlAttrPtr attributeNode = xmlHasProp(node, XMLSTRING(name));
if (NULL != attributeNode)
{
result = [NSXMLNode _objectForNode: (xmlNodePtr)attributeNode];
}
return result;
}
} }
- (NSXMLNode*) attributeForLocalName: (NSString*)localName - (NSXMLNode*) attributeForLocalName: (NSString*)localName
URI: (NSString*)URI URI: (NSString*)URI
{ {
[self notImplemented: _cmd]; NSXMLNode *result = nil;
return nil; xmlNodePtr node = internal->node;
xmlAttrPtr attributeNode = xmlHasNsProp(node, XMLSTRING(localName),
XMLSTRING(URI));
if (NULL != attributeNode)
{
result = [NSXMLNode _objectForNode: (xmlNodePtr)attributeNode];
}
return result;
} }
- (void) addNamespace: (NSXMLNode*)aNamespace - (void) addNamespace: (NSXMLNode*)aNamespace
{ {
xmlNsPtr ns = (xmlNsPtr)[aNamespace _node]; xmlNsPtr ns = (xmlNsPtr)[aNamespace _node];
xmlNodePtr node = internal->node;
if (internal->node->nsDef == NULL) if (node->nsDef == NULL)
{ {
internal->node->nsDef = ns; node->nsDef = ns;
[self _addSubNode: aNamespace];
} }
else else
{ {
xmlNsPtr cur = internal->node->nsDef; xmlNsPtr cur = node->nsDef;
xmlNsPtr last = NULL;
const xmlChar *prefix = ns->prefix; const xmlChar *prefix = ns->prefix;
while (xmlStrcmp(prefix, cur->prefix) != 0) while (xmlStrcmp(prefix, cur->prefix) != 0)
@ -289,19 +395,43 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
if (cur->next == NULL) if (cur->next == NULL)
{ {
cur->next = ns; cur->next = ns;
[self _addSubNode: aNamespace];
return; return;
} }
last = cur;
cur = cur->next; cur = cur->next;
} }
// Found the same prefix
if (cur->href == NULL)
{
// This was a fake namespace we added
if (node->ns == cur)
{
node->ns = ns;
}
if (last == NULL)
{
node->nsDef = ns;
}
else
{
last->next = ns;
}
ns->next = cur->next;
cur->next = NULL;
}
} }
[self _addSubNode: aNamespace]; // FIXME: Need to replace fake namespaces in subnodes
} }
- (void) removeNamespaceForPrefix: (NSString*)name - (void) removeNamespaceForPrefix: (NSString*)name
{ {
if (internal->node->nsDef != NULL) xmlNodePtr node = internal->node;
if (node->nsDef != NULL)
{ {
xmlNsPtr cur = internal->node->nsDef; xmlNsPtr cur = node->nsDef;
xmlNsPtr last = NULL; xmlNsPtr last = NULL;
const xmlChar *prefix = XMLSTRING(name); const xmlChar *prefix = XMLSTRING(name);
@ -318,6 +448,10 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
last->next = cur->next; last->next = cur->next;
} }
cur->next = NULL; cur->next = NULL;
if (node->ns == cur)
{
node->ns = NULL;
}
if (cur->_private != NULL) if (cur->_private != NULL)
{ {
[self _removeSubNode: (NSXMLNode *)cur->_private]; [self _removeSubNode: (NSXMLNode *)cur->_private];
@ -350,13 +484,14 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
- (NSArray*) namespaces - (NSArray*) namespaces
{ {
// FIXME: Should use xmlGetNsList() // FIXME: Should we use xmlGetNsList()?
NSMutableArray *result = nil; NSMutableArray *result = nil;
xmlNsPtr ns = internal->node->nsDef; xmlNsPtr ns = internal->node->nsDef;
if (ns) if (ns)
{ {
xmlNsPtr cur = NULL; xmlNsPtr cur = NULL;
result = [NSMutableArray array]; result = [NSMutableArray array];
for (cur = ns; cur != NULL; cur = cur->next) for (cur = ns; cur != NULL; cur = cur->next)
{ {
@ -369,20 +504,13 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
- (NSXMLNode*) namespaceForPrefix: (NSString*)name - (NSXMLNode*) namespaceForPrefix: (NSString*)name
{ {
// FIXME: Should use xmlSearchNs() const xmlChar *prefix = XMLSTRING(name);
xmlNsPtr ns = internal->node->nsDef; xmlNodePtr node = internal->node;
xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
if (ns) if (ns)
{ {
const xmlChar *prefix = XMLSTRING(name); return [NSXMLNode _objectForNode: (xmlNodePtr)ns];
xmlNsPtr cur = NULL;
for (cur = ns; cur != NULL; cur = cur->next)
{
if (xmlStrcmp(prefix, cur->prefix) == 0)
{
return [NSXMLNode _objectForNode: (xmlNodePtr)cur];
}
}
} }
return nil; return nil;
@ -402,21 +530,12 @@ GS_PRIVATE_INTERNAL(NSXMLElement)
- (NSString*) resolvePrefixForNamespaceURI: (NSString*)namespaceURI - (NSString*) resolvePrefixForNamespaceURI: (NSString*)namespaceURI
{ {
// FIXME Should use xmlSearchNsByHref() const xmlChar *uri = XMLSTRING(namespaceURI);
xmlNsPtr ns = internal->node->nsDef; xmlNsPtr ns = xmlSearchNsByHref(internal->node->doc, internal->node, uri);
if (ns) if (ns)
{ {
const xmlChar *uri = XMLSTRING(namespaceURI); return StringFromXMLStringPtr(ns->prefix);
xmlNsPtr cur;
for (cur = ns; cur != NULL; cur = cur->next)
{
if (xmlStrcmp(uri, cur->href) == 0)
{
return StringFromXMLStringPtr(cur->prefix);
}
}
} }
return nil; return nil;

View file

@ -451,7 +451,28 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
xmlNodePtr curNode = [self _childNodeAtIndex: index]; xmlNodePtr curNode = [self _childNodeAtIndex: index];
BOOL mergeTextNodes = NO; // is there a defined option for this? BOOL mergeTextNodes = NO; // is there a defined option for this?
if (mergeTextNodes || childNode->type == XML_ATTRIBUTE_NODE) if (childNode->type == XML_NAMESPACE_DECL)
{
// FIXME
return;
}
else
{
#if LIBXML_VERSION >= 20620
xmlDocPtr tmp = childNode->doc;
if (tmp)
{
xmlDOMWrapAdoptNode(NULL, childNode->doc, childNode,
parentNode->doc, parentNode, 0);
xmlFreeDoc(tmp);
}
#endif
}
if (mergeTextNodes ||
((childNode->type != XML_TEXT_NODE) &&
(parentNode->type != XML_TEXT_NODE)))
{ {
// this uses the built-in libxml functions which merge adjacent text nodes // this uses the built-in libxml functions which merge adjacent text nodes
xmlNodePtr addedNode = NULL; xmlNodePtr addedNode = NULL;
@ -466,33 +487,23 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
} }
if (addedNode != childNode) if (addedNode != childNode)
{ {
[child _setNode: NULL]; if (addedNode != NULL)
child = [NSXMLNode _objectForNode: addedNode]; {
// The node was freed while merging
[child _invalidate];
}
// Don't add as subnode
return;
} }
} }
else if (childNode->type == XML_NAMESPACE_DECL)
{
// FIXME
}
else else
{ {
/* here we avoid merging adjacent text nodes by linking /* here we avoid merging adjacent text nodes by linking
* the new node in "by hand" * the new node in "by hand"
*/ */
xmlDocPtr tmp = childNode->doc;
if (tmp)
{
xmlDOMWrapAdoptNode(NULL, childNode->doc, childNode,
parentNode->doc, parentNode, 0);
xmlFreeDoc(tmp);
}
else
{
xmlSetTreeDoc(childNode, parentNode->doc);
}
childNode->parent = parentNode; childNode->parent = parentNode;
xmlSetTreeDoc(childNode, parentNode->doc);
if (curNode) if (curNode)
{ {
// insert childNode before an existing node curNode // insert childNode before an existing node curNode
@ -532,6 +543,7 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
} }
[self _addSubNode: child]; [self _addSubNode: child];
// FIXME: Need to replace fake namespaces in subnodes
} }
- (void) _invalidate - (void) _invalidate
@ -833,12 +845,20 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
const xmlChar *xmlName = XMLSTRING(name); const xmlChar *xmlName = XMLSTRING(name);
xmlChar *prefix = NULL; xmlChar *prefix = NULL;
xmlChar *localName; xmlChar *localName;
NSString *result = name;
if (NULL == xmlName) if (NULL == xmlName)
return nil; return nil;
localName = xmlSplitQName2(xmlName, &prefix); localName = xmlSplitQName2(xmlName, &prefix);
return StringFromXMLStringPtr(localName); if (NULL != localName)
{
result = StringFromXMLStringPtr(localName);
xmlFree(localName);
xmlFree(prefix);
}
return result;
} }
+ (id) namespaceWithName: (NSString*)name + (id) namespaceWithName: (NSString*)name
@ -887,21 +907,22 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
+ (NSString*) prefixForName: (NSString*)name + (NSString*) prefixForName: (NSString*)name
{ {
const xmlChar *xmlName = XMLSTRING(name); const xmlChar *xmlName = XMLSTRING(name);
xmlChar *localName;
xmlChar *prefix = NULL; xmlChar *prefix = NULL;
NSString *result = @"";
if (NULL == xmlName) if (NULL == xmlName)
return nil; return nil;
xmlSplitQName2(xmlName, &prefix); localName = xmlSplitQName2(xmlName, &prefix);
if (NULL != prefix)
{
result = StringFromXMLStringPtr(prefix);
xmlFree(localName);
xmlFree(prefix);
}
if (NULL == prefix) return result;
{
return @"";
}
else
{
return StringFromXMLStringPtr(prefix);
}
} }
+ (id) processingInstructionWithName: (NSString*)name + (id) processingInstructionWithName: (NSString*)name
@ -1049,7 +1070,10 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
if (node->type == XML_NAMESPACE_DECL) if (node->type == XML_NAMESPACE_DECL)
{ {
((xmlNsPtr)node)->_private = NULL; ((xmlNsPtr)node)->_private = NULL;
xmlFreeNode(node); // FIXME: Not sure when to free the node here,
// the same namespace node might be referenced
// from other places.
//xmlFreeNode(node);
} }
else else
{ {
@ -1099,6 +1123,7 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
} }
else else
{ {
#if LIBXML_VERSION >= 20620
if (node->doc) if (node->doc)
{ {
/* Create a private document and move the node over. /* Create a private document and move the node over.
@ -1112,6 +1137,7 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
xmlDOMWrapAdoptNode(NULL, node->doc, node, tmp, NULL, 0); xmlDOMWrapAdoptNode(NULL, node->doc, node, tmp, NULL, 0);
} }
else else
#endif
{ {
// separate our node from its parent and siblings // separate our node from its parent and siblings
xmlUnlinkNode(node); xmlUnlinkNode(node);
@ -1253,12 +1279,22 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
} }
case NSXMLEntityDeclarationKind: case NSXMLEntityDeclarationKind:
// FIXME ... xmlNewEntity doesn't exist in common version of libxml2 #if LIBXML_VERSION >= 20700
/*
node = xmlNewEntity(NULL, (xmlChar *)"", 0, (xmlChar *)"", node = xmlNewEntity(NULL, (xmlChar *)"", 0, (xmlChar *)"",
(xmlChar *)"", (xmlChar *)""); (xmlChar *)"", (xmlChar *)"");
*/ #else
node = xmlNewNode(NULL, (xmlChar *)""); {
xmlEntityPtr ret;
ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
memset(ret, 0, sizeof(xmlEntity));
ret->type = XML_ENTITY_DECL;
ret->name = xmlStrdup((xmlChar *)"");
ret->ExternalID = xmlStrdup((xmlChar *)"");
ret->SystemID = xmlStrdup((xmlChar *)"");
ret->content = xmlStrdup((xmlChar *)"");
node = ret;
}
#endif
break; break;
case NSXMLNotationDeclarationKind: case NSXMLNotationDeclarationKind:
@ -1333,11 +1369,6 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
} }
- (NSString*) localName - (NSString*) localName
{
return [[self class] localNameForName: [self name]];
}
- (NSString*) name
{ {
xmlNodePtr node = internal->node; xmlNodePtr node = internal->node;
@ -1356,6 +1387,23 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
} }
} }
- (NSString*) name
{
NSString *localName = [self localName];
if (nil != localName)
{
NSString *prefix = [self prefix];
if ((nil != prefix) && [prefix length] > 0)
{
return [NSString stringWithFormat: @"%@:%@", prefix, localName];
}
}
return localName;
}
- (NSXMLNode*) _nodeFollowingInNaturalDirection: (BOOL)forward - (NSXMLNode*) _nodeFollowingInNaturalDirection: (BOOL)forward
{ {
NSXMLNode *ancestor = self; NSXMLNode *ancestor = self;
@ -1440,7 +1488,26 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
- (NSString*) prefix - (NSString*) prefix
{ {
return [[self class] prefixForName: [self name]]; xmlNodePtr node = internal->node;
if (NULL == node)
{
return nil;
}
if (XML_NAMESPACE_DECL == node->type)
{
return nil;
}
if (XML_ELEMENT_NODE != node->type)
{
return @"";
}
if (node->ns == NULL)
{
return @"";
}
return StringFromXMLStringPtr(node->ns->prefix);
} }
- (NSXMLNode*) previousNode - (NSXMLNode*) previousNode
@ -1510,7 +1577,76 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
} }
else else
{ {
xmlNodeSetName(node, XMLSTRING(name)); const xmlChar *xmlName = XMLSTRING(name);
xmlChar *prefix = NULL;
xmlChar *localName;
if (NULL == xmlName)
{
xmlNodeSetName(node, (const xmlChar *)"");
return;
}
localName = xmlSplitQName2(xmlName, &prefix);
if (localName != NULL)
{
// FIXME: Which other nodes get namespaces?
if ((node->type == XML_ATTRIBUTE_NODE) ||
(node->type == XML_ELEMENT_NODE))
{
xmlNsPtr ns;
// Set namespace
if (node->doc == NULL)
{
#if LIBXML_VERSION >= 20620
// Create a private document for this node
xmlDocPtr tmp = xmlNewDoc((xmlChar *)"1.0");
xmlDOMWrapAdoptNode(NULL, NULL, node, tmp, NULL, 0);
#endif
}
ns = xmlSearchNs(node->doc, node, prefix);
if (ns)
{
xmlSetNs(node, ns);
}
else
{
// FIXME: Fake the name space and fix it later
// xmlReconciliateNs or xmlDOMWrapReconcileNamespaces ?
// This function is private, so re reimplemt it.
//ns = xmlDOMWrapStoreNs(node->doc, NULL, prefix);
xmlNsPtr oldNs = node->doc->oldNs;
while (oldNs)
{
if (xmlStrEqual(oldNs->prefix, prefix))
{
ns = oldNs;
break;
}
if (oldNs->next == NULL)
{
ns = xmlNewNs(NULL, NULL, prefix);
oldNs->next = ns;
break;
}
oldNs = oldNs->next;
}
xmlSetNs(node, ns);
}
}
xmlNodeSetName(node, localName);
xmlFree(localName);
xmlFree(prefix);
}
else
{
xmlNodeSetName(node, xmlName);
}
} }
} }
@ -1610,9 +1746,21 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
} }
#endif #endif
#if LIBXML_VERSION >= 20623
ctxt = xmlSaveToBuffer(buffer, "utf-8", xmlOptions); ctxt = xmlSaveToBuffer(buffer, "utf-8", xmlOptions);
xmlSaveTree(ctxt, internal->node); xmlSaveTree(ctxt, internal->node);
error = xmlSaveClose(ctxt); error = xmlSaveClose(ctxt);
#else
{
xmlDocPtr doc = NULL;
if (internal->node->type != XML_NAMESPACE_DECL)
{
doc = internal->node->doc;
}
error = xmlNodeDump(buffer, doc, internal->node, 1, 1);
}
#endif
if (-1 == error) if (-1 == error)
{ {
xmlBufferFree(buffer); xmlBufferFree(buffer);