#include <libxml/tree.h>
#include <libxml/encoding.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/xmlIO.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxml/globals.h>
#include <stdio.h>
#ifdef XS_WARNINGS
#define xs_warn(string) warn("%s",string)
#else
#define xs_warn(string)
#endif
void
domAddNsDef(xmlNodePtr tree, xmlNsPtr ns)
{
xmlNsPtr i = tree->nsDef;
while(i != NULL && i != ns)
i = i->next;
if( i == NULL )
{
ns->next = tree->nsDef;
tree->nsDef = ns;
}
}
char
domRemoveNsDef(xmlNodePtr tree, xmlNsPtr ns)
{
xmlNsPtr i = tree->nsDef;
if( ns == tree->nsDef )
{
tree->nsDef = tree->nsDef->next;
ns->next = NULL;
return(1);
}
while( i != NULL )
{
if( i->next == ns )
{
i->next = ns->next;
ns->next = NULL;
return(1);
}
i = i->next;
}
return(0);
}
xmlNsPtr
_domAddNsChain(xmlNsPtr c, xmlNsPtr ns)
{
if( c == NULL )
return(ns);
else
{
xmlNsPtr i = c;
while(i != NULL && i != ns)
i = i->next;
if(i == NULL)
{
ns->next = c;
return(ns);
}
}
return(c);
}
void
_domReconcileNsAttr(xmlAttrPtr attr, xmlNsPtr * unused)
{
xmlNodePtr tree = attr->parent;
if (tree == NULL)
return;
if( attr->ns != NULL )
{
xmlNsPtr ns;
if ((attr->ns->prefix != NULL) &&
(xmlStrEqual(attr->ns->prefix, BAD_CAST "xml"))) {
ns = xmlSearchNsByHref(tree->doc, tree, XML_XML_NAMESPACE);
attr->ns = ns;
return;
} else {
ns = xmlSearchNs( tree->doc, tree->parent, attr->ns->prefix );
}
if( ns != NULL && ns->href != NULL && attr->ns->href != NULL &&
xmlStrcmp(ns->href,attr->ns->href) == 0 )
{
if( domRemoveNsDef(tree, attr->ns) )
*unused = _domAddNsChain(*unused, attr->ns);
attr->ns = ns;
}
else
{
if( domRemoveNsDef(tree, attr->ns) )
domAddNsDef(tree, attr->ns);
else
{
attr->ns = xmlCopyNamespace(attr->ns);
if (attr->ns) {
domAddNsDef(tree, attr->ns);
}
}
}
}
}
void
_domReconcileNs(xmlNodePtr tree, xmlNsPtr * unused)
{
if( tree->ns != NULL )
{
xmlNsPtr ns = xmlSearchNs( tree->doc, tree->parent, tree->ns->prefix );
if( ns != NULL && ns->href != NULL && tree->ns->href != NULL &&
xmlStrcmp(ns->href,tree->ns->href) == 0 )
{
if( domRemoveNsDef(tree, tree->ns) )
*unused = _domAddNsChain(*unused, tree->ns);
tree->ns = ns;
}
else
{
if( domRemoveNsDef(tree, tree->ns) ) {
domAddNsDef(tree, tree->ns);
}
else
{
tree->ns = xmlCopyNamespace(tree->ns);
domAddNsDef(tree, tree->ns);
}
}
}
if( tree->type == XML_ELEMENT_NODE )
{
xmlElementPtr ele = (xmlElementPtr) tree;
xmlAttrPtr attr = (xmlAttrPtr) ele->attributes;
while( attr != NULL )
{
_domReconcileNsAttr(attr, unused);
attr = attr->next;
}
}
{
xmlNodePtr child = tree->children;
while( child != NULL )
{
_domReconcileNs(child, unused);
child = child->next;
}
}
}
void
domReconcileNs(xmlNodePtr tree)
{
xmlNsPtr unused = NULL;
_domReconcileNs(tree, &unused);
if( unused != NULL )
xmlFreeNsList(unused);
}
int
domParseChar( xmlChar *cur, int *len )
{
unsigned char c;
unsigned int val;
if ( cur == NULL || *cur == 0 ) {
*len = 0;
return(0);
}
c = *cur;
if ( c & 0x80 ) {
if ((c & 0xe0) == 0xe0) {
if ((c & 0xf0) == 0xf0) {
*len = 4;
val = (cur[0] & 0x7) << 18;
val |= (cur[1] & 0x3f) << 12;
val |= (cur[2] & 0x3f) << 6;
val |= cur[3] & 0x3f;
} else {
*len = 3;
val = (cur[0] & 0xf) << 12;
val |= (cur[1] & 0x3f) << 6;
val |= cur[2] & 0x3f;
}
} else {
*len = 2;
val = (cur[0] & 0x1f) << 6;
val |= cur[1] & 0x3f;
}
if ( !IS_CHAR(val) ) {
*len = -1;
return(0);
}
return(val);
}
else {
*len = 1;
return((int)c);
}
}
xmlNodePtr
domReadWellBalancedString( xmlDocPtr doc, xmlChar* block, int repair ) {
int retCode = -1;
xmlNodePtr nodes = NULL;
if ( block ) {
retCode = xmlParseBalancedChunkMemory( doc,
NULL,
NULL,
0,
block,
&nodes );
if ( retCode != 0 && repair == 0 ) {
xmlFreeNodeList( nodes );
nodes = NULL;
}
else {
xmlSetListDoc(nodes,doc);
}
}
return nodes;
}
int
domAddNodeToList(xmlNodePtr cur, xmlNodePtr leader, xmlNodePtr followup)
{
xmlNodePtr c1 = NULL, c2 = NULL, p = NULL;
if ( cur ) {
c1 = c2 = cur;
if( leader ) {
p = leader->parent;
}
else if( followup ) {
p = followup->parent;
}
else {
return 0;
}
if ( cur->type == XML_DOCUMENT_FRAG_NODE ) {
c1 = cur->children;
while ( c1 ){
c1->parent = p;
c1 = c1->next;
}
c1 = cur->children;
c2 = cur->last;
cur->last = cur->children = NULL;
}
else {
cur->parent = p;
}
if (c1 && 2 && c1!=leader) {
if ( leader ) {
leader->next = c1;
c1->prev = leader;
}
else if ( p ) {
p->children = c1;
}
if ( followup ) {
followup->prev = c2;
c2->next = followup;
}
else if ( p ) {
p->last = c2;
}
}
return 1;
}
return 0;
}
int
domIsParent( xmlNodePtr cur, xmlNodePtr ref ) {
xmlNodePtr helper = NULL;
if ( cur == NULL
|| ref == NULL
|| cur->doc != ref->doc
|| ref->children == NULL
|| cur->parent == (xmlNodePtr)cur->doc
|| cur->parent == NULL ) {
return 0;
}
if( ref->type == XML_DOCUMENT_NODE ) {
return 1;
}
helper= cur;
while ( helper && (xmlDocPtr) helper != cur->doc ) {
if( helper == ref ) {
return 1;
}
helper = helper->parent;
}
return 0;
}
int
domTestHierarchy(xmlNodePtr cur, xmlNodePtr ref)
{
if ( !ref || !cur || cur->type == XML_ATTRIBUTE_NODE ) {
return 0;
}
switch ( ref->type ){
case XML_ATTRIBUTE_NODE:
case XML_DOCUMENT_NODE:
return 0;
break;
default:
break;
}
if ( domIsParent( cur, ref ) ) {
return 0;
}
return 1;
}
int
domTestDocument(xmlNodePtr cur, xmlNodePtr ref)
{
if ( cur->type == XML_DOCUMENT_NODE ) {
switch ( ref->type ) {
case XML_ATTRIBUTE_NODE:
case XML_ELEMENT_NODE:
case XML_ENTITY_NODE:
case XML_ENTITY_REF_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_NAMESPACE_DECL:
return 0;
break;
default:
break;
}
}
return 1;
}
void
domUnlinkNode( xmlNodePtr node ) {
if ( node == NULL
|| ( node->prev == NULL
&& node->next == NULL
&& node->parent == NULL ) ) {
return;
}
if ( node->prev != NULL ) {
node->prev->next = node->next;
}
if ( node->next != NULL ) {
node->next->prev = node->prev;
}
if ( node->parent != NULL ) {
if ( node == node->parent->last ) {
node->parent->last = node->prev;
}
if ( node == node->parent->children ) {
node->parent->children = node->next;
}
}
node->prev = NULL;
node->next = NULL;
node->parent = NULL;
}
xmlNodePtr
domImportNode( xmlDocPtr doc, xmlNodePtr node, int move, int reconcileNS ) {
xmlNodePtr return_node = node;
if ( move ) {
return_node = node;
if ( node->type != XML_DTD_NODE ) {
domUnlinkNode( node );
}
}
else {
if ( node->type == XML_DTD_NODE ) {
return_node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
}
else {
return_node = xmlCopyNode( node, 1 );
}
}
if ( node && doc && node->doc != doc ) {
xmlSetTreeDoc(return_node, doc);
}
if ( reconcileNS && doc && return_node
&& return_node->type != XML_ENTITY_REF_NODE ) {
domReconcileNs(return_node);
}
return return_node;
}
xmlChar*
domName(xmlNodePtr node) {
const xmlChar *prefix = NULL;
const xmlChar *name = NULL;
xmlChar *qname = NULL;
if ( node == NULL ) {
return NULL;
}
switch ( node->type ) {
case XML_XINCLUDE_START :
case XML_XINCLUDE_END :
case XML_ENTITY_REF_NODE :
case XML_ENTITY_NODE :
case XML_DTD_NODE :
case XML_ENTITY_DECL :
case XML_DOCUMENT_TYPE_NODE :
case XML_PI_NODE :
case XML_NOTATION_NODE :
case XML_NAMESPACE_DECL :
name = node->name;
break;
case XML_COMMENT_NODE :
name = (const xmlChar *) "#comment";
break;
case XML_CDATA_SECTION_NODE :
name = (const xmlChar *) "#cdata-section";
break;
case XML_TEXT_NODE :
name = (const xmlChar *) "#text";
break;
case XML_DOCUMENT_NODE :
case XML_HTML_DOCUMENT_NODE :
case XML_DOCB_DOCUMENT_NODE :
name = (const xmlChar *) "#document";
break;
case XML_DOCUMENT_FRAG_NODE :
name = (const xmlChar *) "#document-fragment";
break;
case XML_ELEMENT_NODE :
case XML_ATTRIBUTE_NODE :
if ( node->ns != NULL ) {
prefix = node->ns->prefix;
}
name = node->name;
break;
case XML_ELEMENT_DECL :
prefix = ((xmlElementPtr) node)->prefix;
name = node->name;
break;
case XML_ATTRIBUTE_DECL :
prefix = ((xmlAttributePtr) node)->prefix;
name = node->name;
break;
}
if ( prefix != NULL ) {
qname = xmlStrdup( prefix );
qname = xmlStrcat( qname , (const xmlChar *) ":" );
qname = xmlStrcat( qname , name );
}
else {
qname = xmlStrdup( name );
}
return qname;
}
xmlNodePtr
domAppendChild( xmlNodePtr self,
xmlNodePtr newChild ){
xmlNodePtr fragment = NULL;
if ( self == NULL ) {
return newChild;
}
if ( !(domTestHierarchy(self, newChild)
&& domTestDocument(self, newChild))){
xs_warn("HIERARCHY_REQUEST_ERR\n");
xmlGenericError(xmlGenericErrorContext,"HIERARCHY_REQUEST_ERR\n");
return NULL;
}
if ( newChild->doc == self->doc ){
domUnlinkNode( newChild );
}
else {
xs_warn("WRONG_DOCUMENT_ERR - non conform implementation\n");
newChild = domImportNode( self->doc, newChild, 1, 0 );
}
if ( self->children != NULL ) {
if (newChild->type == XML_DOCUMENT_FRAG_NODE )
fragment = newChild->children;
domAddNodeToList( newChild, self->last, NULL );
}
else if (newChild->type == XML_DOCUMENT_FRAG_NODE ) {
xmlNodePtr c1 = NULL;
self->children = newChild->children;
fragment = newChild->children;
c1 = fragment;
while ( c1 ){
c1->parent = self;
c1 = c1->next;
}
self->last = newChild->last;
newChild->last = newChild->children = NULL;
}
else {
self->children = newChild;
self->last = newChild;
newChild->parent= self;
}
if ( fragment ) {
newChild = fragment;
while ( fragment ) {
domReconcileNs(fragment);
fragment = fragment->next;
}
}
else if ( newChild->type != XML_ENTITY_REF_NODE ) {
domReconcileNs(newChild);
}
return newChild;
}
xmlNodePtr
domRemoveChild( xmlNodePtr self, xmlNodePtr old ) {
if ( self == NULL || old == NULL ) {
return NULL;
}
if ( old->type == XML_ATTRIBUTE_NODE
|| old->type == XML_NAMESPACE_DECL ) {
return NULL;
}
if ( self != old->parent ) {
return NULL;
}
domUnlinkNode( old );
if ( old->type == XML_ELEMENT_NODE ) {
domReconcileNs( old );
}
return old ;
}
xmlNodePtr
domReplaceChild( xmlNodePtr self, xmlNodePtr new, xmlNodePtr old ) {
if ( self== NULL )
return NULL;
if ( new == old )
return new;
if ( new == NULL ) {
return domRemoveChild( self, old );
}
if ( old == NULL ) {
domAppendChild( self, new );
return old;
}
if ( !(domTestHierarchy(self, new)
&& domTestDocument(self, new))){
xs_warn("HIERARCHY_REQUEST_ERR\n");
xmlGenericError(xmlGenericErrorContext,"HIERARCHY_REQUEST_ERR\n");
return NULL;
}
if ( new->doc == self->doc ) {
domUnlinkNode( new );
}
else {
new = domImportNode( self->doc, new, 1, 1 );
}
if( old == self->children && old == self->last ) {
domRemoveChild( self, old );
domAppendChild( self, new );
}
else if ( new->type == XML_DOCUMENT_FRAG_NODE
&& new->children == NULL ) {
domRemoveChild( self, old );
}
else {
domAddNodeToList(new, old->prev, old->next );
old->parent = old->next = old->prev = NULL;
}
return old;
}
xmlNodePtr
domInsertBefore( xmlNodePtr self,
xmlNodePtr newChild,
xmlNodePtr refChild ){
xmlNodePtr fragment = NULL;
if ( refChild == newChild ) {
return newChild;
}
if ( self == NULL || newChild == NULL ) {
return NULL;
}
if ( refChild != NULL ) {
if ( refChild->parent != self
|| ( newChild->type == XML_DOCUMENT_FRAG_NODE
&& newChild->children == NULL ) ) {
xmlGenericError(xmlGenericErrorContext,"NOT_FOUND_ERR\n");
return NULL;
}
}
if ( self->children == NULL ) {
return domAppendChild( self, newChild );
}
if ( !(domTestHierarchy( self, newChild )
&& domTestDocument( self, newChild ))) {
xmlGenericError(xmlGenericErrorContext,"HIERARCHY_REQUEST_ERR\n");
return NULL;
}
if ( self->doc == newChild->doc ){
domUnlinkNode( newChild );
}
else {
newChild = domImportNode( self->doc, newChild, 1, 0 );
}
if ( newChild->type == XML_DOCUMENT_FRAG_NODE ) {
fragment = newChild->children;
}
if ( refChild == NULL ) {
domAddNodeToList(newChild, self->last, NULL);
}
else {
domAddNodeToList(newChild, refChild->prev, refChild);
}
if ( fragment ) {
newChild = fragment;
while ( fragment && fragment != refChild ) {
domReconcileNs(fragment);
fragment = fragment->next;
}
} else if ( newChild->type != XML_ENTITY_REF_NODE ) {
domReconcileNs(newChild);
}
return newChild;
}
xmlNodePtr
domInsertAfter( xmlNodePtr self,
xmlNodePtr newChild,
xmlNodePtr refChild ){
if ( refChild == NULL ) {
return domInsertBefore( self, newChild, NULL );
}
return domInsertBefore( self, newChild, refChild->next );
}
xmlNodePtr
domReplaceNode( xmlNodePtr oldNode, xmlNodePtr newNode ) {
xmlNodePtr prev = NULL, next = NULL, par = NULL, fragment = NULL;
if ( oldNode == NULL
|| newNode == NULL ) {
return NULL;
}
if ( oldNode->type == XML_ATTRIBUTE_NODE
|| newNode->type == XML_ATTRIBUTE_NODE
|| newNode->type == XML_DOCUMENT_NODE
|| domIsParent( newNode, oldNode ) ) {
xmlGenericError(xmlGenericErrorContext,"HIERARCHY_REQUEST_ERR\n");
return NULL;
}
par = oldNode->parent;
prev = oldNode->prev;
next = oldNode->next;
if ( oldNode->_private == NULL ) {
xmlUnlinkNode( oldNode );
}
else {
domUnlinkNode( oldNode );
}
if ( newNode->type == XML_DOCUMENT_FRAG_NODE ) {
fragment = newNode->children;
}
if( prev == NULL && next == NULL ) {
domAppendChild( par , newNode );
}
else {
domAddNodeToList( newNode, prev, next );
}
if ( fragment ) {
while ( fragment && fragment != next ) {
domReconcileNs(fragment);
fragment = fragment->next;
}
} else if ( newNode->type != XML_ENTITY_REF_NODE ) {
domReconcileNs(newNode);
}
return oldNode;
}
xmlChar*
domGetNodeValue( xmlNodePtr n ) {
xmlChar * retval = NULL;
if( n != NULL ) {
switch ( n->type ) {
case XML_ATTRIBUTE_NODE:
case XML_ENTITY_DECL:
case XML_TEXT_NODE:
case XML_COMMENT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
break;
default:
return retval;
break;
}
if ( n->type != XML_ENTITY_DECL ) {
retval = xmlXPathCastNodeToString(n);
}
else {
if ( n->content != NULL ) {
xs_warn(" dublicate content\n" );
retval = xmlStrdup(n->content);
}
else if ( n->children != NULL ) {
xmlNodePtr cnode = n->children;
xs_warn(" use child content\n" );
while (cnode) {
xmlBufferPtr buffer = xmlBufferCreate();
xmlNodeDump( buffer, n->doc, cnode, 0, 0 );
if ( buffer->content != NULL ) {
xs_warn( "add item" );
if ( retval != NULL ) {
retval = xmlStrcat( retval, buffer->content );
}
else {
retval = xmlStrdup( buffer->content );
}
}
xmlBufferFree( buffer );
cnode = cnode->next;
}
}
}
}
return retval;
}
void
domSetNodeValue( xmlNodePtr n , xmlChar* val ){
if ( n == NULL )
return;
if ( val == NULL ){
val = (xmlChar *) "";
}
if( n->type == XML_ATTRIBUTE_NODE ){
if ( n->children != NULL ) {
n->last = NULL;
xmlFreeNodeList( n->children );
}
n->children = xmlNewText( val );
n->children->parent = n;
n->children->doc = n->doc;
n->last = n->children;
}
else {
xmlNodeSetContent( n, val );
}
}
void
domSetParentNode( xmlNodePtr self, xmlNodePtr p ) {
if( self && !domIsParent(self, p)) {
if( self->parent != p ){
xmlUnlinkNode( self );
self->parent = p;
if( p->doc != self->doc ) {
self->doc = p->doc;
}
}
}
}
xmlNodeSetPtr
domGetElementsByTagName( xmlNodePtr n, xmlChar* name ){
xmlNodeSetPtr rv = NULL;
xmlNodePtr cld = NULL;
if ( n != NULL && name != NULL ) {
cld = n->children;
while ( cld != NULL ) {
if ( xmlStrcmp( name, cld->name ) == 0 ){
if ( rv == NULL ) {
rv = xmlXPathNodeSetCreate( cld ) ;
}
else {
xmlXPathNodeSetAdd( rv, cld );
}
}
cld = cld->next;
}
}
return rv;
}
xmlNodeSetPtr
domGetElementsByTagNameNS( xmlNodePtr n, xmlChar* nsURI, xmlChar* name ){
xmlNodeSetPtr rv = NULL;
if ( nsURI == NULL ) {
return domGetElementsByTagName( n, name );
}
if ( n != NULL && name != NULL ) {
xmlNodePtr cld = n->children;
while ( cld != NULL ) {
if ( xmlStrcmp( name, cld->name ) == 0
&& cld->ns != NULL
&& xmlStrcmp( nsURI, cld->ns->href ) == 0 ){
if ( rv == NULL ) {
rv = xmlXPathNodeSetCreate( cld ) ;
}
else {
xmlXPathNodeSetAdd( rv, cld );
}
}
cld = cld->next;
}
}
return rv;
}
xmlNsPtr
domNewNs ( xmlNodePtr elem , xmlChar *prefix, xmlChar *href ) {
xmlNsPtr ns = NULL;
if (elem != NULL) {
ns = xmlSearchNs( elem->doc, elem, prefix );
}
if (ns == NULL) {
ns = xmlNewNs( elem , href , prefix );
} else {
if (!xmlStrEqual(href, ns->href)) {
ns = NULL;
}
}
return ns;
}
xmlAttrPtr
domGetAttrNode(xmlNodePtr node, const xmlChar *qname) {
xmlChar * prefix = NULL;
xmlChar * localname = NULL;
xmlAttrPtr ret = NULL;
xmlNsPtr ns = NULL;
if ( qname == NULL || node == NULL )
return NULL;
ret = xmlHasNsProp(node, qname, NULL);
if ( ret == NULL ) {
localname = xmlSplitQName2(qname, &prefix);
if ( localname != NULL ) {
ns = xmlSearchNs( node->doc, node, prefix );
if ( ns != NULL ) {
ret = xmlHasNsProp( node, localname, ns->href );
}
if ( prefix != NULL) {
xmlFree( prefix );
}
xmlFree( localname );
}
}
if (ret && ret->type != XML_ATTRIBUTE_NODE) {
return NULL;
}
else {
return ret;
}
}
xmlAttrPtr
domSetAttributeNode( xmlNodePtr node, xmlAttrPtr attr ) {
if ( node == NULL || attr == NULL ) {
return attr;
}
if ( attr != NULL && attr->type != XML_ATTRIBUTE_NODE )
return NULL;
if ( node == attr->parent ) {
return attr;
}
if ( attr->doc != node->doc ){
attr = (xmlAttrPtr) domImportNode( node->doc, (xmlNodePtr) attr, 1, 1 );
}
else {
xmlUnlinkNode( (xmlNodePtr) attr );
}
if ( attr != NULL ) {
if (node->properties == NULL) {
node->properties = attr;
} else {
xmlAttrPtr prev = node->properties;
while (prev->next != NULL) prev = prev->next;
prev->next = attr;
attr->prev = prev;
}
}
return attr;
}
void
domAttrSerializeContent(xmlBufferPtr buffer, xmlAttrPtr attr)
{
xmlNodePtr children;
children = attr->children;
while (children != NULL) {
switch (children->type) {
case XML_TEXT_NODE:
xmlAttrSerializeTxtContent(buffer, attr->doc,
attr, children->content);
break;
case XML_ENTITY_REF_NODE:
xmlBufferAdd(buffer, BAD_CAST "&", 1);
xmlBufferAdd(buffer, children->name,
xmlStrlen(children->name));
xmlBufferAdd(buffer, BAD_CAST ";", 1);
break;
default:
break;
}
children = children->next;
}
}
int
domNodeNormalize( xmlNodePtr node );
int
domNodeNormalizeList( xmlNodePtr nodelist )
{
if ( nodelist == NULL )
return(0);
while ( nodelist ){
if ( domNodeNormalize( nodelist ) == 0 )
return(0);
nodelist = nodelist->next;
}
return(1);
}
int
domNodeNormalize( xmlNodePtr node )
{
xmlNodePtr next = NULL;
if ( node == NULL )
return(0);
switch ( node->type ) {
case XML_TEXT_NODE:
while ( node->next
&& node->next->type == XML_TEXT_NODE ) {
next = node->next;
xmlNodeAddContent(node, next->content);
xmlUnlinkNode( next );
if ( !next->_private )
xmlFreeNode( next );
}
break;
case XML_ELEMENT_NODE:
domNodeNormalizeList( (xmlNodePtr) node->properties );
case XML_ATTRIBUTE_NODE:
return( domNodeNormalizeList( node->children ) );
break;
default:
break;
}
return(1);
}
int
domRemoveNsRefs(xmlNodePtr tree, xmlNsPtr ns) {
xmlAttrPtr attr;
xmlNodePtr node = tree;
if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) return(0);
while (node != NULL) {
if (node->ns == ns)
node->ns = NULL;
attr = node->properties;
while (attr != NULL) {
if (attr->ns == ns)
attr->ns = NULL;
attr = attr->next;
}
if (node->children != NULL && node->type != XML_ENTITY_REF_NODE) {
node = node->children;
} else if ((node != tree) && (node->next != NULL)) {
node = node->next;
} else if (node != tree) {
while (node != tree) {
if (node->parent != NULL)
node = node->parent;
if ((node != tree) && (node->next != NULL)) {
node = node->next;
break;
}
if (node->parent == NULL) {
node = NULL;
break;
}
}
if (node == tree)
node = NULL;
} else
break;
}
return(1);
}