Annotation of win32/gnome/gdome2-x.x.x/libgdome/gdomecore/gdome-xml-node.c, revision 1.1

1.1     ! paf         1: /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
        !             2: /* gdome-xml-node.c
        !             3:  *
        !             4:  * Copyright (C) 1999 Raph Levien <raph@acm.org>
        !             5:  * Copyright (C) 2000 Mathieu Lacage <mathieu@gnu.org>
        !             6:  * Copyright (C) 2000 Anders Carlsson <andersca@gnu.org>
        !             7:  * Copyright (C) 2001 Paolo Casarini <paolo@casarini.org>
        !             8:  *
        !             9:  * This library is free software; you can redistribute it and/or
        !            10:  * modify it under the terms of the GNU Lesser General Public
        !            11:  * License as published by the Free Software Foundation; either
        !            12:  * version 2.1 of the License, or (at your option) any later version.
        !            13:  * 
        !            14:  * This library is distributed in the hope that it will be useful,
        !            15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            17:  * Lesser General Public License for more details.
        !            18:  * 
        !            19:  * You should have received a copy of the GNU Lesser General Public
        !            20:  * License along with this library; if not, write to the Free Software
        !            21:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            22:  */
        !            23: 
        !            24: #ifdef HAVE_CONFIG_H
        !            25: #  include <config.h>
        !            26: #endif
        !            27: //paf #include <sys/time.h>
        !            28: //paf #include <unistd.h>
        !            29: #include <stdlib.h>
        !            30: #include <string.h>
        !            31: #include "gdome.h"
        !            32: #include "gdome-events.h"
        !            33: #include "gdome-refdebug.h"
        !            34: #include "gdome-treegc.h"
        !            35: #include <libxml/tree.h>
        !            36: #include <libxml/parser.h>
        !            37: #include <libxml/xmlmemory.h>
        !            38: #include <libxml/hash.h>
        !            39: #include "gdome-xml-util.h"
        !            40: #include "gdome-xml-xmlmemory.h"
        !            41: #include "gdome-xml-xmlutil.h"
        !            42: #include "gdome-xml-xmldtdutil.h"
        !            43: #include "gdome-xml-str.h"
        !            44: #include "gdome-evt-event.h"
        !            45: #include "gdome-evt-eventl.h"
        !            46: #include "gdome-evt-mevent.h"
        !            47: #include "gdome-evt-propagation.h"
        !            48: #include "gdome-xml-nodel.h"
        !            49: #include "gdome-xml-node.h"
        !            50: #include "gdome-xml-document.h"
        !            51: #include "gdome-xml-element.h"
        !            52: #include "gdome-xml-attribute.h"
        !            53: #include "gdome-xml-cdata.h"
        !            54: #include "gdome-xml-entityref.h"
        !            55: #include "gdome-xml-text.h"
        !            56: #include "gdome-xml-cdatas.h"
        !            57: #include "gdome-xml-comment.h"
        !            58: #include "gdome-xml-entity.h"
        !            59: #include "gdome-xml-pi.h"
        !            60: #include "gdome-xml-notation.h"
        !            61: #include "gdome-xml-documentt.h"
        !            62: #include "gdome-xml-documentf.h"
        !            63: #include "gdome-xml-domimpl.h"
        !            64: #include "gdome-xpath.h"
        !            65: #include "gdome-xml-xpns.h"
        !            66: 
        !            67: /* indexed by node type 
        !            68:   first one is NULL because there 
        !            69:    is no node type number 0 
        !            70:    cf: spec p25 (DOM 1). interface Node.
        !            71: */
        !            72: const void * gdome_xml_vtabs[] = {
        !            73:  NULL, 
        !            74:  &gdome_xml_el_vtab,
        !            75:  &gdome_xml_a_vtab,
        !            76:  &gdome_xml_t_vtab,
        !            77:  &gdome_xml_cds_vtab,
        !            78:  &gdome_xml_er_vtab,
        !            79:  &gdome_xml_ent_vtab,
        !            80:  &gdome_xml_pi_vtab,
        !            81:  &gdome_xml_c_vtab,
        !            82:  &gdome_xml_doc_vtab, 
        !            83:  &gdome_xml_dt_vtab,
        !            84:  &gdome_xml_df_vtab,
        !            85:  &gdome_xml_not_vtab,
        !            86:  &gdome_xml_doc_vtab,
        !            87:   &gdome_xml_dt_vtab,
        !            88:   NULL,
        !            89:   NULL,
        !            90:   &gdome_xml_ent_vtab
        !            91: };
        !            92: 
        !            93: /***************
        !            94:  * Virtual Table
        !            95:  **************/
        !            96: const GdomeNodeVtab gdome_xml_n_vtab = 
        !            97: {
        !            98:  gdome_xml_n_ref,
        !            99:  gdome_xml_n_unref,
        !           100:  gdome_xml_n_query_interface,
        !           101:  gdome_xml_n_nodeName,
        !           102:  gdome_xml_n_nodeValue,
        !           103:  gdome_xml_n_set_nodeValue,
        !           104:  gdome_xml_n_nodeType,
        !           105:  gdome_xml_n_parentNode,
        !           106:  gdome_xml_n_childNodes,
        !           107:  gdome_xml_n_firstChild,
        !           108:  gdome_xml_n_lastChild,
        !           109:  gdome_xml_n_previousSibling,
        !           110:  gdome_xml_n_nextSibling,
        !           111:  gdome_xml_n_attributes,
        !           112:  gdome_xml_n_ownerDocument,
        !           113:  gdome_xml_n_insertBefore,
        !           114:  gdome_xml_n_replaceChild,
        !           115:  gdome_xml_n_removeChild,
        !           116:  gdome_xml_n_appendChild,
        !           117:  gdome_xml_n_hasChildNodes,
        !           118:  gdome_xml_n_cloneNode,
        !           119:  gdome_xml_n_normalize,
        !           120:  gdome_xml_n_isSupported,
        !           121:  gdome_xml_n_namespaceURI,
        !           122:  gdome_xml_n_prefix,
        !           123:  gdome_xml_n_set_prefix,
        !           124:   gdome_xml_n_localName,
        !           125:   gdome_xml_n_hasAttributes,
        !           126:  gdome_xml_n_addEventListener,
        !           127:  gdome_xml_n_removeEventListener,
        !           128:   gdome_xml_n_dispatchEvent,
        !           129:  gdome_xml_n_subTreeDispatchEvent,
        !           130:   gdome_xml_n_canAppend
        !           131: };
        !           132: 
        !           133: 
        !           134: /* function to get the xmlNode from a GdomeNode */
        !           135: xmlNode *
        !           136: gdome_xml_n_get_xmlNode (GdomeNode *node)
        !           137: {
        !           138:  Gdome_xml_Node *xmlnode;
        !           139: 
        !           140:  xmlnode = (Gdome_xml_Node *)node;
        !           141: 
        !           142:  return xmlnode->n;
        !           143: }
        !           144: 
        !           145: /***********************************************************
        !           146:  ***** Constructor and Reference Count Implementation ******
        !           147:  ***********************************************************/
        !           148: 
        !           149: /**
        !           150:  * gdome_xml_n_mkref:
        !           151:  * @n:  The libxml node of which a Gdome reference is wanted
        !           152:  *
        !           153:  * Constructor of the Node structure.
        !           154:  * Returns: the reference to the Gdome node wanted.
        !           155:  */
        !           156: GdomeNode *
        !           157: gdome_xml_n_mkref (xmlNode *n) {
        !           158:  Gdome_xml_Node *result = NULL;
        !           159:  xmlElementType type;
        !           160: 
        !           161:  if (n == NULL)
        !           162:    return NULL;
        !           163: 
        !           164:  type = n->type;
        !           165:  if (n->_private && type != XML_NAMESPACE_DECL) {
        !           166:    result = (Gdome_xml_Node *)n->_private;
        !           167:    result->refcnt++;
        !           168:  } else {
        !           169:    switch (type) {
        !           170:    case XML_ELEMENT_NODE:
        !           171:    case XML_TEXT_NODE:
        !           172:    case XML_CDATA_SECTION_NODE:
        !           173:    case XML_ENTITY_REF_NODE:
        !           174:    case XML_PI_NODE:
        !           175:    case XML_COMMENT_NODE:
        !           176:    case XML_NOTATION_NODE:
        !           177:    case XML_DOCUMENT_FRAG_NODE:
        !           178:    case XML_ATTRIBUTE_NODE:
        !           179:    case XML_ENTITY_DECL: /*libxml use this instead of XML_ENTITY_NODE*/
        !           180:      result = g_new (Gdome_xml_Node, 1);
        !           181: 
        !           182:      result->refcnt = 1;
        !           183:       result->vtab = (GdomeNodeVtab *)gdome_xml_vtabs[n->type];
        !           184:       result->super.user_data = NULL;
        !           185:       result->n = n;
        !           186:       if (type == XML_NOTATION_NODE || type == XML_ENTITY_NODE || type == XML_ENTITY_DECL)
        !           187:         result->accessType = GDOME_READONLY_NODE;
        !           188:       else
        !           189:         result->accessType = GDOME_READWRITE_NODE;
        !           190:       result->ll = NULL;
        !           191: 
        !           192:      n->_private = result;
        !           193: 
        !           194: #ifdef DEBUG_REFCNT
        !           195:       gdome_refdbg_addRef ((void *)result, GDOME_REFDBG_NODE);
        !           196: #endif
        !           197:       gdome_treegc_addNode ((GdomeNode *)result);
        !           198: 
        !           199:       break;
        !           200:     case XML_DOCUMENT_TYPE_NODE:
        !           201:     case XML_DTD_NODE:
        !           202:       return (GdomeNode *)gdome_xml_dt_mkref ((xmlDtd *)n);
        !           203:    case XML_HTML_DOCUMENT_NODE:
        !           204:    case XML_DOCUMENT_NODE:
        !           205:       return (GdomeNode *)gdome_xml_doc_mkref ((xmlDoc *)n);
        !           206:    case XML_NAMESPACE_DECL:
        !           207:      return (GdomeNode *)gdome_xml_xpns_mkref ((xmlNs *)n);
        !           208:    default:
        !           209:      g_warning ("gdome_xml_n_mkref: invalid node type");
        !           210:      break;
        !           211:    }
        !           212:  }
        !           213:  return (GdomeNode *)result;
        !           214: }
        !           215: 
        !           216: /**
        !           217:  * gdome_xml_n_ref:
        !           218:  * @self:  Node Object ref
        !           219:  * @exc:  Exception Object ref
        !           220:  *
        !           221:  * Increase the reference count of the specified Node.
        !           222:  */
        !           223: void
        !           224: gdome_xml_n_ref (GdomeNode *self, GdomeException *exc) {
        !           225:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           226: 
        !           227:   g_return_if_fail (priv != NULL);
        !           228:   g_return_if_fail (GDOME_XML_IS_N (priv));
        !           229:   g_return_if_fail (exc != NULL);
        !           230: 
        !           231:  priv->refcnt++;
        !           232: }
        !           233: 
        !           234: /**
        !           235:  * gdome_xml_n_unref:
        !           236:  * @self:  Node Object ref
        !           237:  * @exc:  Exception Object ref
        !           238:  *
        !           239:  * Decrease the reference count of the specified Node. Free the Node structure
        !           240:  * if the Node will have zero reference.
        !           241:  */
        !           242: void
        !           243: gdome_xml_n_unref (GdomeNode *self, GdomeException *exc) {
        !           244:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           245:   xmlElementType type;
        !           246: 
        !           247:   g_return_if_fail (priv != NULL);
        !           248:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !           249:   g_return_if_fail (exc != NULL);
        !           250: 
        !           251:   type = gdome_xmlGetType (priv->n);
        !           252:   switch (type) {
        !           253:   case XML_DOCUMENT_TYPE_NODE:
        !           254:   case XML_DTD_NODE:
        !           255:     return gdome_xml_dt_unref (self, exc);
        !           256:   case XML_DOCUMENT_NODE:
        !           257:     return gdome_xml_doc_unref (self, exc);
        !           258:   default:
        !           259:     if (priv->refcnt > 0)
        !           260:       priv->refcnt--;
        !           261: 
        !           262:     if (priv->refcnt == 0 && priv->ll == NULL) {
        !           263:       xmlNode *n = (xmlNode *)priv->n;
        !           264: 
        !           265:      gdome_treegc_delNode (self);
        !           266: 
        !           267:       n->_private = NULL;
        !           268:      if (type != XML_NOTATION_NODE &&
        !           269:          type != XML_ENTITY_DECL &&
        !           270:          n->parent == NULL)
        !           271:        gdome_xmlFreeSubtree (n);
        !           272:      else {
        !           273:        if (type == XML_ATTRIBUTE_NODE)
        !           274:          if (gdome_xmlIsNsDecl ((xmlAttr *)n))
        !           275:            gdome_xmlFreeSubtree (n);
        !           276:      }
        !           277: 
        !           278: #ifdef DEBUG_REFCNT
        !           279:       gdome_refdbg_delRef ((void *)self, GDOME_REFDBG_NODE);
        !           280: #endif
        !           281:       g_free (self);
        !           282:     }
        !           283:   }
        !           284: }
        !           285: 
        !           286: /**
        !           287:  * gdome_xml_n_query_interface:
        !           288:  * @self:  Node Object ref
        !           289:  * @interface:  interface needed
        !           290:  * @exc:  Exception Object ref
        !           291:  *
        !           292:  * Returns: a reference to this object that implements the @interface needed,
        !           293:  *          or %NULL if the @interface is not supported by this Object.
        !           294:  */
        !           295: gpointer
        !           296: gdome_xml_n_query_interface (GdomeNode *self, const char *interface, GdomeException *exc)
        !           297: {
        !           298:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           299: 
        !           300:   g_return_val_if_fail (priv != NULL, NULL);
        !           301:   g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           302:   g_return_val_if_fail (interface != NULL, NULL);
        !           303:   g_return_val_if_fail (exc != NULL, NULL);
        !           304: 
        !           305:   if (!strcmp (interface, "Node") ||
        !           306:       !strcmp (interface, "EventTarget")) {
        !           307:     priv->refcnt++;
        !           308:     return self;
        !           309:   }
        !           310:   else
        !           311:     return NULL;
        !           312: }
        !           313: 
        !           314: /**************************************
        !           315:  ***** Attributes implementation ******
        !           316:  **************************************/
        !           317: 
        !           318: /**
        !           319:  * gdome_xml_n_attributes:
        !           320:  * @self:  Node Object ref
        !           321:  * @exc:  Exception Object ref
        !           322:  *
        !           323:  * Returns: a NamedNodeMap containing the attributes of this node (if it is an
        !           324:  * Element) or %NULL otherwise.
        !           325:  */
        !           326: GdomeNamedNodeMap *
        !           327: gdome_xml_n_attributes (GdomeNode *self, GdomeException *exc)
        !           328: {
        !           329:  g_return_val_if_fail (self != NULL, NULL);
        !           330:  g_return_val_if_fail (GDOME_XML_IS_N (self), NULL);
        !           331:  g_return_val_if_fail (exc != NULL, NULL);
        !           332: 
        !           333:  if (GDOME_XML_IS_EL (self))
        !           334:    return gdome_el_attributes((GdomeElement *)self, exc);
        !           335: 
        !           336:  return NULL;
        !           337: }
        !           338: 
        !           339: /**
        !           340:  * gdome_xml_n_childNodes:
        !           341:  * @self:  Node Object ref
        !           342:  * @exc:  Exception Object ref
        !           343:  *
        !           344:  * Returns: a NodeList that contains all children of this node. If there are no
        !           345:  * children, this is a NodeList containing no nodes.  Note that attributes are
        !           346:  * not considered to be children of element nodes - use gdome_n_attributes to
        !           347:  * obtain the attributes.
        !           348:  */
        !           349: GdomeNodeList *
        !           350: gdome_xml_n_childNodes (GdomeNode *self, GdomeException *exc)
        !           351: {
        !           352:  g_return_val_if_fail (self != NULL, NULL);
        !           353:  g_return_val_if_fail (GDOME_XML_IS_N (self), NULL);
        !           354:  g_return_val_if_fail (exc != NULL, NULL);
        !           355: 
        !           356:   if (GDOME_XML_IS_NS(self))
        !           357:    return NULL;
        !           358: 
        !           359:   return gdome_xml_nl_mkref ((GdomeNode*)self, NULL, NULL, GDOME_READONLY_NODE);
        !           360: }
        !           361: 
        !           362: /**
        !           363:  * gdome_xml_n_firstChild:
        !           364:  * @self:  Node Object ref
        !           365:  * @exc:  Exception Object ref
        !           366:  * 
        !           367:  * Returns: the first child of this node. If there is no such node,
        !           368:  * this returns %NULL.
        !           369:  */
        !           370: GdomeNode *
        !           371: gdome_xml_n_firstChild (GdomeNode *self, GdomeException *exc)
        !           372: {
        !           373:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           374: 
        !           375:  g_return_val_if_fail (priv != NULL, NULL);
        !           376:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           377:  g_return_val_if_fail (exc != NULL, NULL);
        !           378: 
        !           379:   switch (gdome_xmlGetType (priv->n)) {
        !           380:   case XML_DOCUMENT_TYPE_NODE:
        !           381:   case XML_DTD_NODE:
        !           382:   case XML_PI_NODE:
        !           383:   case XML_COMMENT_NODE:
        !           384:   case XML_TEXT_NODE:
        !           385:   case XML_CDATA_SECTION_NODE:
        !           386:   case XML_NOTATION_NODE:
        !           387:   case XML_NAMESPACE_DECL:
        !           388:     return NULL;
        !           389:   case XML_DOCUMENT_NODE:
        !           390:   case XML_DOCUMENT_FRAG_NODE:
        !           391:   case XML_ENTITY_REF_NODE:
        !           392:   case XML_ELEMENT_NODE:
        !           393:   case XML_ATTRIBUTE_NODE:
        !           394:   case XML_ENTITY_NODE:
        !           395:   case XML_ENTITY_DECL:
        !           396:     return gdome_xml_n_mkref (gdome_xmlGetFirstChild (priv->n));
        !           397:   default:
        !           398:     g_warning ("gdome_xml_n_firstChild: invalid node type");
        !           399:     return NULL;
        !           400:   }
        !           401: }
        !           402: 
        !           403: /**
        !           404:  * gdome_xml_n_lastChild:
        !           405:  * @self:  Node Object ref
        !           406:  * @exc:  Exception Object ref
        !           407:  *
        !           408:  * Returns: the last child of this node. If there is no such node,
        !           409:  * this returns %NULL.
        !           410:  */
        !           411: GdomeNode *
        !           412: gdome_xml_n_lastChild (GdomeNode *self, GdomeException *exc)
        !           413: {
        !           414:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           415: 
        !           416:  g_return_val_if_fail (priv != NULL, NULL);
        !           417:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           418:  g_return_val_if_fail (exc != NULL, NULL);
        !           419: 
        !           420:   switch (gdome_xmlGetType (priv->n)) {
        !           421:   case XML_DOCUMENT_TYPE_NODE:
        !           422:   case XML_DTD_NODE:
        !           423:   case XML_PI_NODE:
        !           424:   case XML_COMMENT_NODE:
        !           425:   case XML_TEXT_NODE:
        !           426:   case XML_CDATA_SECTION_NODE:
        !           427:   case XML_NOTATION_NODE:
        !           428:   case XML_NAMESPACE_DECL:
        !           429:     return NULL;
        !           430:   case XML_DOCUMENT_NODE:
        !           431:   case XML_DOCUMENT_FRAG_NODE:
        !           432:   case XML_ENTITY_REF_NODE:
        !           433:   case XML_ELEMENT_NODE:
        !           434:   case XML_ATTRIBUTE_NODE:
        !           435:   case XML_ENTITY_NODE:
        !           436:   case XML_ENTITY_DECL:
        !           437:     return gdome_xml_n_mkref (gdome_xmlGetLastChild (priv->n));
        !           438:   default:
        !           439:     g_warning ("gdome_xml_n_lastChild: invalid node type");
        !           440:     return NULL;
        !           441:   }
        !           442: }
        !           443: 
        !           444: /**
        !           445:  * gdome_xml_n_localName:
        !           446:  * @self:  Node Objects ref
        !           447:  * @exc:  Exception Object ref
        !           448:  *
        !           449:  * Returns: the local part of the qualified name of this node.
        !           450:  * For nodes of any type other than %GDOME_ELEMENT_NODE and
        !           451:  * %GDOME_ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, this is
        !           452:  * always %NULL.
        !           453:  */
        !           454: GdomeDOMString *
        !           455: gdome_xml_n_localName (GdomeNode *self, GdomeException *exc)
        !           456: {
        !           457:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           458: 
        !           459:  g_return_val_if_fail (priv != NULL, NULL);
        !           460:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           461:  g_return_val_if_fail (exc != NULL, NULL);
        !           462: 
        !           463:  if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
        !           464:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE) &&
        !           465:     gdome_xmlGetNs(priv->n) != NULL)
        !           466:    return gdome_xml_str_mkref_dup ((gchar *)gdome_xmlGetName (priv->n));
        !           467:  else
        !           468:    return NULL;
        !           469: }
        !           470: 
        !           471: /**
        !           472:  * gdome_xml_n_namespaceURI:
        !           473:  * @self:  Node Objects ref
        !           474:  * @exc:  Exception Object ref
        !           475:  *
        !           476:  * Returns: the namespace URI of this node, or %NULL if it is unspecified.
        !           477:  * For nodes of any type other than %GDOME_ELEMENT_NODE and
        !           478:  * %GDOME_ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, this is
        !           479:  * always %NULL.
        !           480:  */
        !           481: GdomeDOMString *
        !           482: gdome_xml_n_namespaceURI (GdomeNode *self, GdomeException *exc)
        !           483: {
        !           484:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           485: 
        !           486:  g_return_val_if_fail (priv != NULL, NULL);
        !           487:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           488:  g_return_val_if_fail (exc != NULL, NULL);
        !           489: 
        !           490:  if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
        !           491:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE ||
        !           492:      gdome_xmlGetType(priv->n) == XML_NAMESPACE_DECL) &&
        !           493:     gdome_xmlGetNs(priv->n) != NULL)
        !           494:    return gdome_xml_str_mkref_dup ((gchar *)gdome_xmlGetNsURI (priv->n));
        !           495:  else
        !           496:    return NULL;
        !           497: }
        !           498: 
        !           499: /**
        !           500:  * gdome_xml_n_nextSibling:
        !           501:  * @self:  Node Object ref
        !           502:  * @exc:  Exception Object ref
        !           503:  *
        !           504:  * Returns: the node immediately following this node. If there is no such
        !           505:  * node, this returns %NULL.
        !           506:  */
        !           507: GdomeNode *
        !           508: gdome_xml_n_nextSibling (GdomeNode *self, GdomeException *exc)
        !           509: {
        !           510:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           511: 
        !           512:  g_return_val_if_fail (priv != NULL, NULL);
        !           513:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           514:  g_return_val_if_fail (exc != NULL, NULL);
        !           515: 
        !           516:  if(GDOME_XML_IS_A (priv) || GDOME_XML_IS_NS (priv))
        !           517:    return NULL;
        !           518:  else
        !           519:    return gdome_xml_n_mkref (gdome_xmlGetNext (priv->n));
        !           520: }
        !           521: 
        !           522: /**
        !           523:  * gdome_xml_n_nodeName:
        !           524:  * @self:  Node Object ref
        !           525:  * @exc:  Exception Object ref
        !           526:  *
        !           527:  * Returns: the name of this node, depending on its type.
        !           528:  */
        !           529: GdomeDOMString *
        !           530: gdome_xml_n_nodeName (GdomeNode *self, GdomeException *exc)
        !           531: {
        !           532:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           533:  GdomeDOMString *ret = NULL;
        !           534: 
        !           535:  g_return_val_if_fail (priv != NULL, NULL);
        !           536:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           537:  g_return_val_if_fail (exc != NULL, NULL);
        !           538: 
        !           539:  switch (gdome_xmlGetType (priv->n)) {
        !           540:  case XML_ATTRIBUTE_NODE:
        !           541:    ret = gdome_a_name((GdomeAttr *)self, exc);
        !           542:    break;
        !           543:  case XML_ELEMENT_NODE:
        !           544:    ret = gdome_el_tagName((GdomeElement *)self, exc);
        !           545:    break;
        !           546:   case XML_DOCUMENT_TYPE_NODE:
        !           547:   case XML_DTD_NODE:
        !           548:     ret = gdome_dt_name((GdomeDocumentType *)self, exc);
        !           549:     break;
        !           550:   case XML_PI_NODE:
        !           551:     ret = gdome_pi_target((GdomeProcessingInstruction *)self, exc);
        !           552:    break;
        !           553:   case XML_ENTITY_NODE:
        !           554:   case XML_ENTITY_DECL: /*libxml use this instead of XML_ENTITY_NODE*/
        !           555:  case XML_ENTITY_REF_NODE:
        !           556:  case XML_NOTATION_NODE:
        !           557:    ret = gdome_xml_str_mkref_dup((gchar *)gdome_xmlGetName (priv->n));
        !           558:    break;
        !           559:  case XML_CDATA_SECTION_NODE:
        !           560:    ret = gdome_xml_str_mkref_dup("#cdata-section");
        !           561:    break;
        !           562:  case XML_COMMENT_NODE:
        !           563:    ret = gdome_xml_str_mkref_dup("#comment");
        !           564:    break;
        !           565:  case XML_DOCUMENT_NODE:
        !           566:    ret = gdome_xml_str_mkref_dup("#document");
        !           567:    break;
        !           568:  case XML_DOCUMENT_FRAG_NODE:
        !           569:    ret = gdome_xml_str_mkref_dup("#document-fragment");
        !           570:    break;
        !           571:  case XML_TEXT_NODE:
        !           572:    ret = gdome_xml_str_mkref_dup("#text");
        !           573:    break;
        !           574:   case XML_NAMESPACE_DECL:
        !           575:     ret = gdome_xml_str_mkref_dup(gdome_xmlGetNsPrefix(priv->n));
        !           576:    break;
        !           577:  default:
        !           578:    g_warning ("gdome_n_name: wrong Node Type.");
        !           579:  }
        !           580: 
        !           581:  return ret;
        !           582: }
        !           583: 
        !           584: /**
        !           585:  * gdome_xml_n_nodeType:
        !           586:  * @self:  Node Object ref
        !           587:  * @exc:  Exception Object ref
        !           588:  *
        !           589:  * Returns: an integer bigger than %0 representing the type of the underlying
        !           590:  * object or %0 on error.
        !           591:  */
        !           592: unsigned short
        !           593: gdome_xml_n_nodeType (GdomeNode *self, GdomeException *exc)
        !           594: {
        !           595:   Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           596:   xmlElementType type;
        !           597: 
        !           598:  g_return_val_if_fail (priv != NULL, 0);
        !           599:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
        !           600:  g_return_val_if_fail (exc != NULL, 0);
        !           601: 
        !           602:   type = gdome_xmlGetType(priv->n);
        !           603:   if (type == XML_DTD_NODE)
        !           604:     return XML_DOCUMENT_TYPE_NODE;
        !           605:   else if (type == XML_ENTITY_DECL)
        !           606:     return XML_ENTITY_NODE;
        !           607:  else if (type == XML_NAMESPACE_DECL)
        !           608:    return GDOME_XPATH_NAMESPACE_NODE;
        !           609:   else
        !           610:     return type;
        !           611: }
        !           612: 
        !           613: /**
        !           614:  * gdome_xml_n_nodeValue:
        !           615:  * @self:  Node Object ref
        !           616:  * @exc:  Exception Object ref
        !           617:  *
        !           618:  * Returns: the value of this node, depending on its type.
        !           619:  */
        !           620: GdomeDOMString *
        !           621: gdome_xml_n_nodeValue (GdomeNode *self, GdomeException *exc)
        !           622: {
        !           623:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           624:  GdomeDOMString *ret = NULL;
        !           625: 
        !           626:  g_return_val_if_fail (priv != NULL, 0);
        !           627:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           628:  g_return_val_if_fail (exc != NULL, 0);
        !           629: 
        !           630:  switch (gdome_xmlGetType (priv->n)) {
        !           631:  case XML_ATTRIBUTE_NODE:
        !           632:    ret = gdome_a_value ((GdomeAttr *)self, exc);
        !           633:    break;
        !           634:   case XML_PI_NODE:
        !           635:     ret = gdome_pi_data ((GdomeProcessingInstruction *)self, exc);
        !           636:     break;
        !           637:  case XML_CDATA_SECTION_NODE:
        !           638:  case XML_COMMENT_NODE:
        !           639:  case XML_TEXT_NODE:
        !           640:    ret = gdome_xml_str_mkref_own (xmlNodeGetContent (priv->n));
        !           641:    break;
        !           642:  case XML_ELEMENT_NODE:
        !           643:  case XML_ENTITY_NODE:
        !           644:  case XML_ENTITY_REF_NODE:
        !           645:  case XML_DOCUMENT_NODE:
        !           646:  case XML_DOCUMENT_TYPE_NODE:
        !           647:  case XML_DOCUMENT_FRAG_NODE:
        !           648:   case XML_NOTATION_NODE:
        !           649:   case XML_DTD_NODE:
        !           650:   case XML_ENTITY_DECL:
        !           651:  case XML_NAMESPACE_DECL:
        !           652:    break;
        !           653:  default:
        !           654:    g_warning ("could not recognize the Node Type.");
        !           655:  }
        !           656: 
        !           657:  return ret;
        !           658: }
        !           659: 
        !           660: /**
        !           661:  * gdome_xml_n_ownerDocument:
        !           662:  * @self:  Node Objects ref
        !           663:  * @exc:  Exception Object ref
        !           664:  *
        !           665:  * Returns: the documment object associated with this node. This is also the
        !           666:  * Document object used to create new nodes. When this node is a Document or a
        !           667:  * DocumentType which is not used with any Document yet, this is %NULL.
        !           668:  */
        !           669: GdomeDocument *
        !           670: gdome_xml_n_ownerDocument (GdomeNode *self, GdomeException *exc)
        !           671: {
        !           672:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           673: 
        !           674:  g_return_val_if_fail (priv != NULL, NULL);
        !           675:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           676:  g_return_val_if_fail (exc != NULL, NULL);
        !           677: 
        !           678:   if (gdome_xmlGetType (priv->n) == XML_DOCUMENT_NODE)
        !           679:     return NULL;
        !           680:   else
        !           681:     return (GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n));
        !           682: }
        !           683: 
        !           684: /**
        !           685:  * gdome_xml_n_parentNode:
        !           686:  * @self: Node Object ref
        !           687:  * @exc: Exception Object ref
        !           688:  *
        !           689:  * Returns: the parent of this node. All nodes, except Attr,
        !           690:  * Document, DocumentFragment, Entity, and Notation may have a parent. However,
        !           691:  * if a node has just been created and not yet added to the tree, or if it has
        !           692:  * been removed from the tree, this is %NULL.
        !           693:  */
        !           694: GdomeNode *
        !           695: gdome_xml_n_parentNode (GdomeNode *self, GdomeException *exc)
        !           696: {
        !           697:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           698: 
        !           699:  g_return_val_if_fail (priv != NULL, NULL);
        !           700:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           701:  g_return_val_if_fail (exc != NULL, NULL);
        !           702: 
        !           703:  if(GDOME_XML_IS_TREE_N (priv))
        !           704:    return gdome_xml_n_mkref (gdome_xmlGetParent (priv->n));
        !           705:  else
        !           706:    return NULL;
        !           707: }
        !           708: 
        !           709: /**
        !           710:  * gdome_xml_n_prefix:
        !           711:  * @self:  Node Objects ref
        !           712:  * @exc:  Exception Object ref
        !           713:  *
        !           714:  * Returns: the namespace prefix of this node, or %NULL if it is unspecified.
        !           715:  * For nodes of any type other than %GDOME_ELEMENT_NODE and
        !           716:  * %GDOME_ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, this is
        !           717:  * always %NULL.
        !           718:  */
        !           719: GdomeDOMString *
        !           720: gdome_xml_n_prefix (GdomeNode *self, GdomeException *exc)
        !           721: {
        !           722:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           723: 
        !           724:  g_return_val_if_fail (priv != NULL, 0);
        !           725:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
        !           726:  g_return_val_if_fail (exc != NULL, 0);
        !           727: 
        !           728:  if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
        !           729:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE ||
        !           730:      gdome_xmlGetType(priv->n) == XML_NAMESPACE_DECL) &&
        !           731:     gdome_xmlGetNs(priv->n) != NULL)
        !           732:    return gdome_xml_str_mkref_dup ((gchar *)gdome_xmlGetNsPrefix (priv->n));
        !           733:  else
        !           734:    return NULL;
        !           735: }
        !           736: 
        !           737: /**
        !           738:  * gdome_xml_n_previousSibling:
        !           739:  * @self:  Node Object ref
        !           740:  * @exc:  Exception Object ref
        !           741:  *
        !           742:  * Returns: the node immediately preceding this node. If there is no such
        !           743:  * node, this returns %NULL.
        !           744:  */
        !           745: GdomeNode *
        !           746: gdome_xml_n_previousSibling (GdomeNode *self, GdomeException *exc)
        !           747: {
        !           748:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           749: 
        !           750:  g_return_val_if_fail (priv != NULL, NULL);
        !           751:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           752:  g_return_val_if_fail (exc != NULL, NULL);
        !           753: 
        !           754:  if(GDOME_XML_IS_A (priv) || GDOME_XML_IS_NS (priv))
        !           755:    return NULL;
        !           756:  else
        !           757:    return gdome_xml_n_mkref (gdome_xmlGetPrev (priv->n));
        !           758: }
        !           759: 
        !           760: /**
        !           761:  * gdome_xml_n_set_nodeValue:
        !           762:  * @self:  Node Object ref
        !           763:  * @nodeValue:  The new value for this node.
        !           764:  * @exc:  Exception Object ref
        !           765:  *
        !           766:  * Sets The value of this node, depending on its type.
        !           767:  *
        !           768:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           769:  */
        !           770: void
        !           771: gdome_xml_n_set_nodeValue (GdomeNode *self, GdomeDOMString *nodeValue, GdomeException *exc)
        !           772: {
        !           773:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           774: 
        !           775:  g_return_if_fail (priv != NULL);
        !           776:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !           777:  g_return_if_fail (nodeValue != NULL);
        !           778:   g_return_if_fail (exc != NULL);
        !           779: 
        !           780:   if (GDOME_ISREADONLY (priv)) {
        !           781:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           782:     return;
        !           783:   }
        !           784: 
        !           785:  switch (gdome_xmlGetType(priv->n)) {
        !           786:  case XML_ATTRIBUTE_NODE:
        !           787:    gdome_xml_a_set_value ((GdomeAttr *)self, nodeValue, exc);
        !           788:    break;
        !           789:   case XML_PI_NODE:
        !           790:     gdome_xml_pi_set_data ((GdomeProcessingInstruction *)self, nodeValue, exc);
        !           791:     break;
        !           792:  case XML_CDATA_SECTION_NODE:
        !           793:  case XML_COMMENT_NODE:
        !           794:   case XML_TEXT_NODE:
        !           795:     gdome_xml_cd_set_data ((GdomeCharacterData *)self, nodeValue, exc);
        !           796:    break;
        !           797:  case XML_ELEMENT_NODE:
        !           798:  case XML_ENTITY_NODE:
        !           799:  case XML_ENTITY_REF_NODE:
        !           800:  case XML_DOCUMENT_NODE:
        !           801:  case XML_DOCUMENT_TYPE_NODE:
        !           802:  case XML_DOCUMENT_FRAG_NODE:
        !           803:   case XML_NOTATION_NODE:
        !           804:   case XML_DTD_NODE:
        !           805:   case XML_NAMESPACE_DECL:
        !           806:    break;
        !           807:  default:
        !           808:    g_warning ("could not recognize the Node Type.");
        !           809:   }
        !           810: }
        !           811: 
        !           812: /**
        !           813:  * gdome_xml_n_set_prefix:
        !           814:  * @self:  Node Object ref
        !           815:  * @prefix:  The new prefix for this node.
        !           816:  * @exc:  Exception Object ref
        !           817:  *
        !           818:  * Sets a new nemaspace prefix for this node.
        !           819:  *
        !           820:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           821:  * %GDOME_NAMESPACE_ERR: Raised if the specified @prefix is malformed per the
        !           822:  * Namespaces in XML specification, if the namespaceURI of this node is %NULL,
        !           823:  * if the specified prefix is "xml" and the namespaceURI of this node is
        !           824:  * different from "http://www.w3.org/XML/1998/namespace", if this node is an
        !           825:  * attribute and the specified prefix is "xmlns" and the namespaceURI of this
        !           826:  * node is different from "http://www.w3.org/2000/xmlns/", or if this node is
        !           827:  * an attribute and the qualifiedName of this node is "xmlns".
        !           828:  */
        !           829: void
        !           830: gdome_xml_n_set_prefix (GdomeNode *self, GdomeDOMString *prefix, GdomeException *exc)
        !           831: {
        !           832:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           833:  xmlNs *ns;
        !           834: 
        !           835:  g_return_if_fail (priv != NULL);
        !           836:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !           837:  g_return_if_fail (prefix != NULL);
        !           838:  g_return_if_fail (exc != NULL);
        !           839: 
        !           840:   if (GDOME_ISREADONLY (priv)) {
        !           841:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           842:     return;
        !           843:   }
        !           844: 
        !           845:   if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
        !           846:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE) &&
        !           847:     gdome_xmlGetNs(priv->n) != NULL &&
        !           848:      !xmlStrEqual(gdome_xmlGetNsPrefix (priv->n), (xmlChar *)prefix->str)) {
        !           849: 
        !           850:    /* tests for NAMESPACE_ERR */
        !           851:     gchar *nsURI = (gchar *)gdome_xmlGetNsURI (priv->n);
        !           852:    if (nsURI == NULL ||
        !           853:        (!strcmp (prefix->str, "xml") &&
        !           854:         strcmp (nsURI, "http://www.w3.org/XML/1998/namespace")) ||
        !           855:        (gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE &&
        !           856:         !strcmp (prefix->str, "xmlns") &&
        !           857:         strcmp (nsURI, GDOME_XMLNS_NAMESPACE)) ||
        !           858:        (gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE &&
        !           859:         !strcmp (gdome_xmlGetName(priv->n), "xmlns"))) {
        !           860:      *exc = GDOME_NAMESPACE_ERR;
        !           861:      return;
        !           862:    }
        !           863:    ns = gdome_xmlNewNs (priv->n->doc, gdome_xmlGetNsURI (priv->n), (xmlChar *)prefix->str);
        !           864:    gdome_xmlSetNs(priv->n, ns);
        !           865:  }
        !           866: }
        !           867: 
        !           868: /**************************************
        !           869:  ******* Methods implementation *******
        !           870:  **************************************/
        !           871: 
        !           872: /**
        !           873:  * gdome_xml_n_appendChild:
        !           874:  * @self:  Node Object ref
        !           875:  * @newChild:  The node to add
        !           876:  * @exc:  Exception Object ref
        !           877:  *
        !           878:  * Adds the node @newChild to the end of the list of children of this node.
        !           879:  * If the @newChild is already in the tree, it is first removed. If it is a
        !           880:  * DocumentFragment node, the entire contents of the document fragment are
        !           881:  * moved into the child list of this node
        !           882:  *
        !           883:  * %GDOME_HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
        !           884:  * allow children of the type of the @newChild node, or if the node to append is
        !           885:  * one of this node's ancestors or this node itself.
        !           886:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newChild was created from a different
        !           887:  * document than the one that created this node.
        !           888:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !           889:  * Returns: the node added.
        !           890:  */
        !           891: GdomeNode *
        !           892: gdome_xml_n_appendChild (GdomeNode *self, GdomeNode *newChild, GdomeException *exc)
        !           893: {
        !           894:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           895:  Gdome_xml_Node *new_priv = (Gdome_xml_Node *)newChild;
        !           896:  GdomeMutationEvent *mev;
        !           897:  xmlNode *ret;
        !           898: 
        !           899:  g_return_val_if_fail (priv != NULL, NULL);
        !           900:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           901:  g_return_val_if_fail (new_priv != NULL, NULL);
        !           902:  g_return_val_if_fail (GDOME_XML_IS_N (new_priv), NULL);
        !           903:  g_return_val_if_fail (exc != NULL, NULL);
        !           904: 
        !           905:  if (!gdome_xml_n_canAppend (self, newChild, exc)) {
        !           906:    *exc = GDOME_HIERARCHY_REQUEST_ERR;
        !           907:    return NULL;
        !           908:  }
        !           909: 
        !           910:  if (gdome_xmlGetOwner(new_priv->n) != gdome_xmlGetOwner(priv->n)) {
        !           911:    *exc = GDOME_WRONG_DOCUMENT_ERR;
        !           912:    return NULL;
        !           913:  }
        !           914: 
        !           915:  if (GDOME_ISREADONLY (priv)) {
        !           916:    *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           917:    return NULL;
        !           918:  }
        !           919: 
        !           920:  /* If the newChild is already in the tree, it is first removed. */
        !           921:  if (gdome_xmlGetParent(new_priv->n) != NULL)
        !           922:    gdome_xmlUnlinkChild(gdome_xmlGetParent(new_priv->n), new_priv->n);
        !           923: 
        !           924:  ret = gdome_xmlAppendChild(priv->n, new_priv->n);
        !           925: 
        !           926:  /* Delete children list for DocumentFragment Node */
        !           927:  if (gdome_xmlGetType (new_priv->n) == XML_DOCUMENT_FRAG_NODE) {
        !           928:    gdome_xmlSetFirstChild(new_priv->n, NULL);
        !           929:    gdome_xmlSetLastChild(new_priv->n, NULL);
        !           930:  }
        !           931: 
        !           932:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_EVENT_TYPE)) {
        !           933:    /* Fire DOMNodeInserted */
        !           934:    mev = gdome_evt_mevnt_mkref ();
        !           935:    gdome_xml_n_ref (self, exc);
        !           936:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_EVENT_TYPE,
        !           937:                                             TRUE, FALSE, self,
        !           938:                                             NULL, NULL, NULL, 0, exc);
        !           939:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !           940:    gdome_xml_n_unref (self, exc);
        !           941:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           942:  }
        !           943: 
        !           944:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE)) {
        !           945:    /* Fire DOMNodeInsertedIntoDocument */
        !           946:    mev = gdome_evt_mevnt_mkref ();
        !           947:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE,
        !           948:                                             FALSE, FALSE, NULL,
        !           949:                                             NULL, NULL, NULL, 0, exc);
        !           950:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !           951:    gdome_xml_n_subTreeDispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !           952:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           953:  }
        !           954:  
        !           955:  if (gdome_xml_n_eventEnabledByCode (self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           956:    /* Fire DOMSubtreeModified */
        !           957:    mev = gdome_evt_mevnt_mkref ();
        !           958:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           959:                                             TRUE, FALSE, NULL,
        !           960:                                             NULL, NULL, NULL, 0, exc);
        !           961:    gdome_xml_n_dispatchEvent (self, (GdomeEvent *)mev, exc);
        !           962:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           963:  }
        !           964:  
        !           965:  return gdome_xml_n_mkref (ret);
        !           966: }
        !           967: 
        !           968: /**
        !           969:  * gdome_xml_n_cloneNode:
        !           970:  * @self:  Node Object ref
        !           971:  * @deep:  If true, recursively clone the subtree under the specified node;
        !           972:  *         if false, clone only the node itself (and its attributes, if it is
        !           973:  *         an Element).
        !           974:  * @exc:  Exception Object ref
        !           975:  *
        !           976:  * Makes a duplicate of this node, i.e., serves as a generic copy
        !           977:  * constructor for nodes. The duplicate node has no parent; (parentNode is
        !           978:  * %NULL).
        !           979:  * %GDOME_DOCUMENT_TYPE_NODE, %GDOME_NOTATION_NODE and %GDOME_ENTITY_NODE
        !           980:  * nodes are not supported.
        !           981:  *
        !           982:  * %GDOME_NOT_SUPPORTED_ERR: Raised if the type of node being cloned is not
        !           983:  * supported.
        !           984:  * Returns: the duplicate node.
        !           985:  */
        !           986: GdomeNode *
        !           987: gdome_xml_n_cloneNode (GdomeNode *self, GdomeBoolean deep, GdomeException *exc)
        !           988: {
        !           989:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           990:   xmlNode *n = NULL;
        !           991:   xmlElementType type;
        !           992: 
        !           993:  g_return_val_if_fail (priv != NULL, NULL);
        !           994:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !           995:  g_return_val_if_fail (exc != NULL, NULL);
        !           996: 
        !           997:   type = gdome_xmlGetType (priv->n);
        !           998:   if (type == XML_ENTITY_NODE ||
        !           999:       type == XML_ENTITY_DECL ||
        !          1000:      type == XML_NOTATION_NODE ||
        !          1001:      type == XML_DOCUMENT_TYPE_NODE ||
        !          1002:      type == XML_DTD_NODE ||
        !          1003:      type == XML_NAMESPACE_DECL )
        !          1004:    *exc = GDOME_NOT_SUPPORTED_ERR;
        !          1005:  else if (type == XML_DOCUMENT_NODE)
        !          1006:    n = (xmlNode *)xmlCopyDoc ((xmlDoc *)priv->n, deep);
        !          1007:  else if (type == XML_ATTRIBUTE_NODE) {
        !          1008:    n = (xmlNode *)xmlCopyProp (NULL, (xmlAttr *)priv->n);
        !          1009:    if (gdome_xmlGetOwner (n) == NULL)
        !          1010:      gdome_xmlSetOwner (n , gdome_xmlGetOwner (priv->n));
        !          1011:  }
        !          1012:  else
        !          1013:    n = xmlDocCopyNode (priv->n, gdome_xmlGetOwner(priv->n), deep);
        !          1014: 
        !          1015:  if (*exc)
        !          1016:    return NULL;
        !          1017:   else
        !          1018:    return gdome_xml_n_mkref (n);
        !          1019: }
        !          1020: 
        !          1021: /**
        !          1022:  * gdome_xml_n_hasAttributes:
        !          1023:  * @self:  Node Object ref
        !          1024:  * @exc:  Exception Object ref
        !          1025:  *
        !          1026:  * Returns: %TRUE if this node has any attributes, %FALSE otherwise.
        !          1027:  */
        !          1028: GdomeBoolean
        !          1029: gdome_xml_n_hasAttributes (GdomeNode *self, GdomeException *exc) {
        !          1030:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1031: 
        !          1032:  g_return_val_if_fail (priv != NULL, 0);
        !          1033:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
        !          1034:  g_return_val_if_fail (exc != NULL, 0);
        !          1035: 
        !          1036:  if (GDOME_XML_IS_EL (priv))
        !          1037:    return (gdome_xmlGetAttrList (priv->n) != NULL);
        !          1038:  else
        !          1039:     return FALSE;
        !          1040: }
        !          1041: 
        !          1042: /**
        !          1043:  * gdome_xml_n_hasChildNodes:
        !          1044:  * @self:  Node Object ref
        !          1045:  * @exc:  Exception Object ref
        !          1046:  *
        !          1047:  * Returns: %TRUE if this node has any children, %FALSE otherwise.
        !          1048:  */
        !          1049: GdomeBoolean
        !          1050: gdome_xml_n_hasChildNodes (GdomeNode *self, GdomeException *exc) {
        !          1051:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1052: 
        !          1053:  g_return_val_if_fail (priv != NULL, 0);
        !          1054:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
        !          1055:   g_return_val_if_fail (exc != NULL, 0);
        !          1056: 
        !          1057:   switch (gdome_xmlGetType (priv->n)) {
        !          1058:   case XML_DOCUMENT_TYPE_NODE:
        !          1059:   case XML_DTD_NODE:
        !          1060:   case XML_PI_NODE:
        !          1061:   case XML_COMMENT_NODE:
        !          1062:   case XML_TEXT_NODE:
        !          1063:   case XML_CDATA_SECTION_NODE:
        !          1064:   case XML_NOTATION_NODE:
        !          1065:  case XML_NAMESPACE_DECL:
        !          1066:     return FALSE;
        !          1067:   case XML_DOCUMENT_NODE:
        !          1068:   case XML_DOCUMENT_FRAG_NODE:
        !          1069:   case XML_ENTITY_REF_NODE:
        !          1070:   case XML_ELEMENT_NODE:
        !          1071:   case XML_ATTRIBUTE_NODE:
        !          1072:   case XML_ENTITY_NODE:
        !          1073:   case XML_ENTITY_DECL:
        !          1074:    return (gdome_xmlGetFirstChild (priv->n) != NULL);
        !          1075:   default:
        !          1076:     g_warning ("gdome_xml_n_hasChildNodes: invalid node type");
        !          1077:     return FALSE;
        !          1078:   }
        !          1079: }
        !          1080: 
        !          1081: /**
        !          1082:  * gdome_xml_n_insertBefore:
        !          1083:  * @self:  Node Object ref
        !          1084:  * @newChild:  The new node to put in the child list
        !          1085:  * @refChild:  the reference node, i.e., the node before which the new node
        !          1086:  *             must be inserted.
        !          1087:  * @exc:  Exception Object ref
        !          1088:  *
        !          1089:  * Inserts the node @newChild before the existing child node @refChild. If
        !          1090:  * @refChild is %NULL, insert @newChild at the end of the list of children.
        !          1091:  * If @newChild is a DocumentFragment node, all of its children are inserted,
        !          1092:  * in the same order, before @refChild. If the @newChild is already in the
        !          1093:  * tree, it is first removed.
        !          1094:  *
        !          1095:  * %GDOME_HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
        !          1096:  * allow children of the type of the @newChild node, or if the node to insert is
        !          1097:  * one of this node's ancestors or this node itself.
        !          1098:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newChild was created from a different
        !          1099:  * document than the one that created this node.
        !          1100:  * %GDOME_NOT_FOUND_ERR: Raised if @refChild is not a child of this node.
        !          1101:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !          1102:  * Returns: the node being inserted.
        !          1103:  */
        !          1104: GdomeNode *
        !          1105: gdome_xml_n_insertBefore (GdomeNode *self, GdomeNode *newChild, GdomeNode *refChild, GdomeException *exc)
        !          1106: {
        !          1107:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1108:  Gdome_xml_Node *new_priv = (Gdome_xml_Node *)newChild;
        !          1109:  Gdome_xml_Node *ref_priv = (Gdome_xml_Node *)refChild;
        !          1110:  GdomeMutationEvent *mev;
        !          1111:  xmlNode *ret = NULL;
        !          1112: 
        !          1113:  g_return_val_if_fail (priv != NULL, NULL);
        !          1114:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !          1115:  g_return_val_if_fail (new_priv != NULL, NULL);
        !          1116:  g_return_val_if_fail (GDOME_XML_IS_N (new_priv), NULL);
        !          1117:  g_return_val_if_fail (exc != NULL, NULL);
        !          1118: 
        !          1119:  if (!gdome_xml_n_canAppend (self, newChild, exc)) {
        !          1120:    *exc = GDOME_HIERARCHY_REQUEST_ERR;
        !          1121:    return NULL;
        !          1122:  }
        !          1123: 
        !          1124:  if (gdome_xmlGetOwner(new_priv->n) != gdome_xmlGetOwner(priv->n)) {
        !          1125:    *exc = GDOME_WRONG_DOCUMENT_ERR;
        !          1126:    return NULL;
        !          1127:  }
        !          1128: 
        !          1129:   if (GDOME_ISREADONLY (priv)) {
        !          1130:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !          1131:     return NULL;
        !          1132:   }
        !          1133: 
        !          1134:   /* If refChild is null, insert newChild at the end of the list of children.*/
        !          1135:  if(ref_priv == NULL)
        !          1136:    return gdome_xml_n_appendChild (self, newChild, exc);
        !          1137:  else
        !          1138:    g_return_val_if_fail (GDOME_XML_IS_N (ref_priv), NULL);
        !          1139: 
        !          1140:  /* If the newChild is already in the tree, it is first removed. */
        !          1141:   if (gdome_xmlGetParent(new_priv->n) != NULL) {
        !          1142:    if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_EVENT_TYPE)) {
        !          1143:      /* Fire DOMNodeRemoved */
        !          1144:      mev = gdome_evt_mevnt_mkref ();
        !          1145:      gdome_xml_n_ref (self, exc);
        !          1146:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_EVENT_TYPE,
        !          1147:                                               TRUE, FALSE, self,
        !          1148:                                               NULL, NULL, NULL, 0, exc);
        !          1149:      gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !          1150:      gdome_xml_n_unref (self, exc);
        !          1151:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1152:    }
        !          1153: 
        !          1154:    if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE)) {
        !          1155:      /* Fire DOMNodeRemovedFromDocument */
        !          1156:      mev = gdome_evt_mevnt_mkref ();
        !          1157:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE,
        !          1158:                                               FALSE, FALSE, NULL,
        !          1159:                                               NULL, NULL, NULL, 0, exc);
        !          1160:      gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !          1161:      gdome_xml_n_subTreeDispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !          1162:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1163:    }
        !          1164: 
        !          1165:     gdome_xmlUnlinkChild(gdome_xmlGetParent(new_priv->n), new_priv->n);
        !          1166:   }
        !          1167: 
        !          1168:  if ((ret = gdome_xmlInsertBeforeChild(priv->n, new_priv->n, ref_priv->n)) == NULL) {
        !          1169:    *exc = GDOME_NOT_FOUND_ERR;
        !          1170:    return NULL;
        !          1171:   }
        !          1172: 
        !          1173:   /* Unlink children list for DocumentFragment Node */
        !          1174:   if (gdome_xmlGetType (new_priv->n) == XML_DOCUMENT_FRAG_NODE) {
        !          1175:     gdome_xmlSetFirstChild(new_priv->n, NULL);
        !          1176:     gdome_xmlSetLastChild(new_priv->n, NULL);
        !          1177:   }
        !          1178: 
        !          1179:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_EVENT_TYPE)) {
        !          1180:    /* Fire DOMNodeInserted */
        !          1181:    mev = gdome_evt_mevnt_mkref ();
        !          1182:    gdome_xml_n_ref (self, exc);
        !          1183:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_EVENT_TYPE,
        !          1184:                                             TRUE, FALSE, self,
        !          1185:                                             NULL, NULL, NULL, 0, exc);
        !          1186:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !          1187:    gdome_xml_n_unref (self, exc);
        !          1188:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1189:  }
        !          1190: 
        !          1191:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE)) {
        !          1192:    /* Fire DOMNodeInsertedIntoDocument */
        !          1193:    mev = gdome_evt_mevnt_mkref ();
        !          1194:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE,
        !          1195:                                             FALSE, FALSE, NULL,
        !          1196:                                             NULL, NULL, NULL, 0, exc);
        !          1197:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !          1198:    gdome_xml_n_subTreeDispatchEvent (newChild, (GdomeEvent *)mev, exc);
        !          1199:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1200:  }
        !          1201:  
        !          1202:  if (gdome_xml_n_eventEnabledByCode (self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !          1203:    /* Fire DOMSubtreeModified */
        !          1204:    mev = gdome_evt_mevnt_mkref ();
        !          1205:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !          1206:                                             TRUE, FALSE, NULL,
        !          1207:                                             NULL, NULL, NULL, 0, exc);
        !          1208:    gdome_xml_n_dispatchEvent (self, (GdomeEvent *)mev, exc);
        !          1209:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1210:  }
        !          1211: 
        !          1212:  return gdome_xml_n_mkref (ret);
        !          1213: }
        !          1214: 
        !          1215: /**
        !          1216:  * gdome_xml_n_isSupported:
        !          1217:  * @self:  Node Object ref
        !          1218:  * @feature:  The name of the feature to test.
        !          1219:  * @version:  This is the version number of the feature to test. In Level 2,
        !          1220:  *            version 1, this is the string "2.0". If the version is not
        !          1221:  *            specified, supporting any version of the feature will cause the
        !          1222:  *            method to return %TRUE.
        !          1223:  * @exc:  Exception Object ref
        !          1224:  *
        !          1225:  * Tests whether the DOM implementation implements a specific feature and that
        !          1226:  * feature is supported by this node.
        !          1227:  * Returns: %TRUE if the specified feature is supported on this node, %FALSE
        !          1228:  * otherwise.
        !          1229:  */
        !          1230: GdomeBoolean
        !          1231: gdome_xml_n_isSupported (GdomeNode *self, GdomeDOMString *feature, GdomeDOMString *version, GdomeException *exc)
        !          1232: {
        !          1233:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1234:  GdomeBoolean ret;
        !          1235:   GdomeDOMImplementation *domimpl;
        !          1236: 
        !          1237:  g_return_val_if_fail (priv != NULL, FALSE);
        !          1238:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
        !          1239:  g_return_val_if_fail (feature != NULL, FALSE);
        !          1240:  g_return_val_if_fail (exc != NULL, FALSE);
        !          1241: 
        !          1242:  if (version == NULL)
        !          1243:    return TRUE;
        !          1244: 
        !          1245:  domimpl = gdome_xml_di_mkref();
        !          1246:  ret = gdome_xml_di_hasFeature (domimpl, feature, version, exc);
        !          1247:  gdome_xml_di_unref (domimpl, exc);
        !          1248: 
        !          1249:   return ret;
        !          1250: }
        !          1251: 
        !          1252: /**
        !          1253:  * gdome_xml_n_normalize:
        !          1254:  * @self:  Node Object ref
        !          1255:  * @exc:  Exception Object ref
        !          1256:  *
        !          1257:  * Puts all Text nodes in the full depth of the sub-tree underneath this Node,
        !          1258:  * including attribute nodes, into a "normal" form where only structure (e.g.,
        !          1259:  * elements, comments, processing instructions, CDATA sections, and entity
        !          1260:  * references) separates Text nodes, i.e., there are neither adjacent Text
        !          1261:  * nodes nor empty Text nodes.
        !          1262:  */
        !          1263: void
        !          1264: gdome_xml_n_normalize (GdomeNode *self, GdomeException *exc)
        !          1265: {
        !          1266:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1267:  GdomeNode *child = NULL, *new_child = NULL;
        !          1268:  GdomeNode *next = NULL, *new_next = NULL;
        !          1269:  GdomeDOMString *str = NULL;
        !          1270:  GdomeNode *result = NULL;
        !          1271: 
        !          1272:  g_return_if_fail (priv != NULL);
        !          1273:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !          1274:  g_return_if_fail (exc != NULL);
        !          1275: 
        !          1276:  /* this is a generic implementation, not optimized for speed */
        !          1277:  child = gdome_n_firstChild (self, exc);
        !          1278:  while (child != NULL) {
        !          1279:    unsigned short type;
        !          1280: 
        !          1281:    type = gdome_n_nodeType (child, exc);
        !          1282:    if (type == GDOME_TEXT_NODE) {
        !          1283:      next = gdome_n_nextSibling (child, exc);
        !          1284:      while (next != NULL) {
        !          1285:        if (gdome_n_nodeType (next, exc) != GDOME_TEXT_NODE) {
        !          1286:          gdome_n_unref (next, exc);
        !          1287:          break;
        !          1288:        }
        !          1289:        str = gdome_cd_data ((GdomeCharacterData *)next, exc);
        !          1290:        gdome_cd_appendData ((GdomeCharacterData *)child, str, exc);
        !          1291:        gdome_str_unref (str);
        !          1292:        new_next = gdome_n_nextSibling (next, exc);
        !          1293:        result = gdome_n_removeChild (self, next, exc);
        !          1294:        gdome_n_unref (result, exc);
        !          1295:        gdome_n_unref (next, exc);
        !          1296:        next = new_next;
        !          1297:      }
        !          1298:    } else if (type == GDOME_ELEMENT_NODE) {
        !          1299:      GdomeNamedNodeMap *nnm;
        !          1300:      gulong i, n;
        !          1301: 
        !          1302:      gdome_n_normalize (child, exc);
        !          1303:      nnm = gdome_n_attributes (child, exc);
        !          1304:      n = gdome_nnm_length (nnm, exc);
        !          1305:      for (i = 0; i < n; i++) {
        !          1306:        GdomeNode *attr;
        !          1307: 
        !          1308:        attr = gdome_nnm_item (nnm, i, exc);
        !          1309:        gdome_n_normalize (attr, exc);
        !          1310:        gdome_n_unref (attr, exc);
        !          1311:      }
        !          1312:      gdome_nnm_unref (nnm, exc);
        !          1313:    }
        !          1314:    new_child = gdome_n_nextSibling (child, exc);
        !          1315:    gdome_n_unref (child, exc);
        !          1316:    child = new_child;
        !          1317:  }
        !          1318: }
        !          1319: 
        !          1320: /**
        !          1321:  * gdome_xml_n_removeChild:
        !          1322:  * @self:  Node Object ref
        !          1323:  * @oldChild:  The node being removed
        !          1324:  * @exc:  Exception Object ref
        !          1325:  *
        !          1326:  * Removes the child node indicated by @oldChild from the list of children, and
        !          1327:  * returns it.
        !          1328:  *
        !          1329:  * %GDOME_NOT_FOUND_ERR: Raised if @oldChild is not a child of this node.
        !          1330:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !          1331:  * Returns: the node removed.
        !          1332:  */
        !          1333: GdomeNode *
        !          1334: gdome_xml_n_removeChild (GdomeNode *self, GdomeNode *oldChild, GdomeException *exc)
        !          1335: {
        !          1336:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1337:  Gdome_xml_Node *old_priv = (Gdome_xml_Node *)oldChild;
        !          1338:  GdomeMutationEvent *mev;
        !          1339:  xmlNode *ret;
        !          1340: 
        !          1341:  g_return_val_if_fail (priv != NULL, NULL);
        !          1342:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
        !          1343:  g_return_val_if_fail (old_priv != NULL, NULL);
        !          1344:  g_return_val_if_fail (GDOME_XML_IS_TREE_N (old_priv), NULL);
        !          1345:  g_return_val_if_fail (exc != NULL, NULL);
        !          1346: 
        !          1347:   if (GDOME_ISREADONLY (priv)) {
        !          1348:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !          1349:     return NULL;
        !          1350:   }
        !          1351: 
        !          1352:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_EVENT_TYPE)) {
        !          1353:    /* Fire DOMNodeRemoved */
        !          1354:    mev = gdome_evt_mevnt_mkref ();
        !          1355:    gdome_xml_n_ref (self, exc);
        !          1356:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_EVENT_TYPE,
        !          1357:                                             TRUE, FALSE, self,
        !          1358:                                             NULL, NULL, NULL, 0, exc);
        !          1359:    gdome_xml_n_dispatchEvent (oldChild, (GdomeEvent *)mev, exc);
        !          1360:    gdome_xml_n_unref (self, exc);
        !          1361:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1362:  }
        !          1363: 
        !          1364:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE)) {
        !          1365:    /* Fire DOMNodeRemovedFromDocument */
        !          1366:    mev = gdome_evt_mevnt_mkref ();
        !          1367:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE,
        !          1368:                                             FALSE, FALSE, NULL,
        !          1369:                                             NULL, NULL, NULL, 0, exc);
        !          1370:    gdome_xml_n_dispatchEvent (oldChild, (GdomeEvent *)mev, exc);
        !          1371:    gdome_xml_n_subTreeDispatchEvent (oldChild, (GdomeEvent *)mev, exc);
        !          1372:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1373:  }
        !          1374: 
        !          1375:  if (gdome_xml_n_eventEnabledByCode (self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !          1376:    /* Fire DOMSubtreeModified */
        !          1377:    mev = gdome_evt_mevnt_mkref ();
        !          1378:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !          1379:                                             TRUE, FALSE, NULL,
        !          1380:                                             NULL, NULL, NULL, 0, exc);
        !          1381:    gdome_xml_n_dispatchEvent (self, (GdomeEvent *)mev, exc);
        !          1382:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !          1383:  }
        !          1384: 
        !          1385:   if ((ret = gdome_xmlUnlinkChild(priv->n, old_priv->n)) == NULL) {
        !          1386:    *exc = GDOME_NOT_FOUND_ERR;
        !          1387:    return NULL;
        !          1388:   }
        !          1389: 
        !          1390:   return gdome_xml_n_mkref (ret);
        !          1391: }
        !          1392: 
        !          1393: /**
        !          1394:  * gdome_xml_n_replaceChild:
        !          1395:  * @self:  Node Object ref
        !          1396:  * @newChild:  The new node to put in the child list
        !          1397:  * @oldChild:  The node being replaced in the list
        !          1398:  * @exc:  Exception Object ref
        !          1399:  *
        !          1400:  * Replaces the child node @oldChild with @newChild in the list of children,
        !          1401:  * and returns the @oldChild node. If @newChild is a DocumentFragment object,
        !          1402:  * @oldChild is replaced by all of the DocumentFragment children, which are
        !          1403:  * inserted in the same order. If the @newChild is already in the tree, it is
        !          1404:  * first removed.
        !          1405:  *
        !          1406:  * %GDOME_HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does
        !          1407:  * not allow children of the type of the @newChild node, or if the node to put
        !          1408:  * in is one of this node's ancestors or this node itself.
        !          1409:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newChild was created from a different
        !          1410:  * document than the one that created this node.
        !          1411:  * %GDOME_NOT_FOUND_ERR: Raised if @oldChild is not a child of this node.
        !          1412:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
        !          1413:  * Returns: the node replaced.
        !          1414:  */
        !          1415: GdomeNode *
        !          1416: gdome_xml_n_replaceChild (GdomeNode *self, GdomeNode *newChild, GdomeNode *oldChild, GdomeException *exc)
        !          1417: {
        !          1418:  GdomeNode *ret = NULL;
        !          1419:  GdomeNode *refChild = NULL;
        !          1420: 
        !          1421:  g_return_val_if_fail (self != NULL, NULL);
        !          1422:  g_return_val_if_fail (GDOME_XML_IS_N (self), NULL);
        !          1423:  g_return_val_if_fail (newChild != NULL, NULL);
        !          1424:  g_return_val_if_fail (GDOME_XML_IS_N (newChild), NULL);
        !          1425:  g_return_val_if_fail (oldChild != NULL, NULL);
        !          1426:  g_return_val_if_fail (GDOME_XML_IS_N (oldChild), NULL);
        !          1427:  g_return_val_if_fail (exc != NULL, NULL);
        !          1428: 
        !          1429:   if (GDOME_ISREADONLY (self)) {
        !          1430:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !          1431:     return NULL;
        !          1432:   }
        !          1433: 
        !          1434:   refChild = gdome_n_nextSibling (oldChild, exc);
        !          1435:  if (gdome_n_removeChild (self, oldChild, exc)) {
        !          1436:    if (gdome_n_insertBefore (self, newChild, refChild, exc)) {
        !          1437:      gdome_n_unref (newChild, exc);
        !          1438:       ret = oldChild;
        !          1439:    } else {
        !          1440:      gdome_n_unref (oldChild, exc);
        !          1441:      ret = NULL;
        !          1442:    }
        !          1443:  }
        !          1444: 
        !          1445:  if (refChild)
        !          1446:    gdome_n_unref (refChild, exc);
        !          1447: 
        !          1448:   return ret;
        !          1449: }
        !          1450: 
        !          1451: /**
        !          1452:  * gdome_xml_n_addEventListener:
        !          1453:  * @self:  Node Object ref
        !          1454:  * @type:  the event type for which the user is registering
        !          1455:  * @listener:  the listener parameter takes an interface implemented by the
        !          1456:  *             user which contains the methods to be called when the event occurs.
        !          1457:  * @useCapture:  if %TRUE, useCapture indicates that the user wishes to initiate
        !          1458:  *               capture. After initiating capture, all events of the specified
        !          1459:  *               type will be dispatched to the registered EventListener before
        !          1460:  *               being dispatched to any EventTargets beneath them in the tree.
        !          1461:  *               Events which are bubbling upward through the tree will not
        !          1462:  *               trigger an EventListener designated to use capture.
        !          1463:  * @exc:  Exception Object ref
        !          1464:  *
        !          1465:  * This method allows the registration of event listeners on the event target.
        !          1466:  * If an EventListener is added to an EventTarget while it is processing an
        !          1467:  * event, it will not be triggered by the current actions but may be triggered
        !          1468:  * during a later stage of event flow, such as the bubbling phase.
        !          1469:  * If multiple identical EventListeners are registered on the same EventTarget
        !          1470:  * with the same parameters the duplicate instances are discarded. They do not
        !          1471:  * cause the EventListener to be called twice and since they are discarded
        !          1472:  * they do not need to be removed with the removeEventListener method.
        !          1473:  */
        !          1474: void
        !          1475: gdome_xml_n_addEventListener (GdomeNode *self, GdomeDOMString *type,
        !          1476:                               GdomeEventListener *listener, GdomeBoolean useCapture,
        !          1477:                               GdomeException *exc)
        !          1478: {
        !          1479:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1480:  Gdome_xml_ListenerList *ll = NULL;
        !          1481:  Gdome_xml_ListenerList *temp;
        !          1482:   guint32 codeType;
        !          1483: 
        !          1484:  g_return_if_fail (priv != NULL);
        !          1485:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !          1486:  g_return_if_fail (listener != NULL);
        !          1487:  g_return_if_fail (type != NULL);
        !          1488:  g_return_if_fail (exc != NULL);
        !          1489: 
        !          1490:  /* duplicate instances are discarted */
        !          1491:   codeType = gdome_evt_evnt_codeOfName (type->str);
        !          1492:  temp = priv->ll;
        !          1493:  while (temp) {
        !          1494:    if (temp->listener == listener &&
        !          1495:        temp->type == codeType &&
        !          1496:        temp->useCapture == useCapture) {
        !          1497:      return;
        !          1498:    }
        !          1499:    temp = temp->next;
        !          1500:  }
        !          1501: 
        !          1502:  /* create a new ListenerList entry*/
        !          1503:  ll = g_new (Gdome_xml_ListenerList, 1);
        !          1504:  ll->type = codeType;
        !          1505:  gdome_evt_evntl_ref (listener, exc);
        !          1506:  ll->listener = listener;
        !          1507:  ll->useCapture = useCapture;
        !          1508: 
        !          1509:  /* add it at begin of the ListenerList of the target */
        !          1510:  ll->next = priv->ll;
        !          1511:  priv->ll = ll;
        !          1512: }
        !          1513: 
        !          1514: /**
        !          1515:  * gdome_xml_n_removeEventListener:
        !          1516:  * @self:  Node Object ref
        !          1517:  * @type:  Specifies the event type of the EventListener being removed.
        !          1518:  * @listener:  The EventListener parameter indicates the EventListener to be
        !          1519:  *             removed.
        !          1520:  * @useCapture:  Specifies whether the EventListener being removed was
        !          1521:  *               registered as a capturing listener or not. If a listener was
        !          1522:  *               registered twice, one with capture and one without, each must
        !          1523:  *               be removed separately. Removal of a capturing listener does
        !          1524:  *               not affect a non-capturing version of the same listener, and
        !          1525:  *               vice versa.
        !          1526:  * @exc:  Exception Object ref
        !          1527:  *
        !          1528:  * This method allows the removal of event listeners from the event target. If
        !          1529:  * an EventListener is removed from an EventTarget while it is processing an
        !          1530:  * event, it will not be triggered by the current actions. EventListeners can
        !          1531:  * never be invoked after being removed. Calling removeEventListener with
        !          1532:  * arguments which do not identify any currently registered EventListener on
        !          1533:  * the EventTarget has no effect.
        !          1534:  */
        !          1535: void
        !          1536: gdome_xml_n_removeEventListener (GdomeNode *self, GdomeDOMString *type, 
        !          1537:                                 GdomeEventListener *listener, GdomeBoolean useCapture, 
        !          1538:                                 GdomeException *exc)
        !          1539: {
        !          1540:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1541:   Gdome_xml_ListenerList *temp, *prev = NULL;
        !          1542:   guint32 codeType;
        !          1543: 
        !          1544:  g_return_if_fail (priv != NULL);
        !          1545:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !          1546:  g_return_if_fail (listener != NULL);
        !          1547:  g_return_if_fail (type != NULL);
        !          1548:  g_return_if_fail (exc != NULL);
        !          1549: 
        !          1550:   codeType = gdome_evt_evnt_codeOfName (type->str);
        !          1551:   temp = priv->ll;
        !          1552:  while (temp) {
        !          1553:     if (useCapture == temp->useCapture &&
        !          1554:         temp->listener == listener &&
        !          1555:         temp->type == codeType) {
        !          1556:         if (prev)
        !          1557:           prev->next = temp->next;
        !          1558:         else {
        !          1559:           g_assert (priv->ll == temp);
        !          1560:           priv->ll = priv->ll->next;
        !          1561:         }
        !          1562:         temp->next = NULL;
        !          1563:         gdome_evt_evntl_unref (listener, exc);
        !          1564:         g_free (temp);
        !          1565:         break;
        !          1566:     }
        !          1567:     prev = temp;
        !          1568:    temp = temp->next;
        !          1569:  }
        !          1570: }
        !          1571: 
        !          1572: 
        !          1573: /**
        !          1574:  * gdome_xml_n_dispatchEvent:
        !          1575:  * @self:  Node Object ref
        !          1576:  * @evt:  Specifies the event type, behavior, and contextual information to be
        !          1577:  *        used in processing the event.
        !          1578:  * @exc:  Exception Object ref
        !          1579:  *
        !          1580:  * This method allows the dispatch of events into the implementations event
        !          1581:  * model. Events dispatched in this manner will have the same capturing and
        !          1582:  * bubbling behavior as events dispatched directly by the implementation. The
        !          1583:  * target of the event is the EventTarget on which dispatchEvent is called.
        !          1584:  *
        !          1585:  * GDOME_UNSPECIFIED_EVENT_TYPE_ERR: Raised if the Event's type was not
        !          1586:  * specified by initializing the event before dispatchEvent was called.
        !          1587:  * Specification of the Event's type as %NULL or an empty string will also
        !          1588:  * trigger this exception.
        !          1589:  * Returns: if preventDefault was called the value is %FALSE, else the value
        !          1590:  *          is %TRUE.
        !          1591:  */
        !          1592: GdomeBoolean
        !          1593: gdome_xml_n_dispatchEvent (GdomeNode *self, GdomeEvent *evt, GdomeException *exc)
        !          1594: {
        !          1595:   Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1596:   Gdome_evt_Event *ev_priv = (Gdome_evt_Event *)evt;
        !          1597: 
        !          1598:  g_return_val_if_fail (priv != NULL, FALSE);
        !          1599:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
        !          1600:  g_return_val_if_fail (evt != NULL, FALSE);
        !          1601:   g_return_val_if_fail (exc != NULL, FALSE);
        !          1602: 
        !          1603:   if (ev_priv->type == 0) {
        !          1604:     *exc = GDOME_EVENT_EXCEPTION + GDOME_UNSPECIFIED_EVENT_TYPE_ERR;
        !          1605:     return FALSE;
        !          1606:   }
        !          1607: 
        !          1608:   gdome_xml_n_ref (self, exc);
        !          1609:  ev_priv->target = self;
        !          1610:   gdome_evt_fireEvent (evt);
        !          1611:   gdome_xml_n_unref (self, exc);
        !          1612:  
        !          1613:  return !ev_priv->default_prevented;
        !          1614: }
        !          1615: 
        !          1616: /**
        !          1617:  * gdome_xml_n_subTreeDispatchEvent:
        !          1618:  * @self:  Node Object ref
        !          1619:  * @evt:  Specifies the event type, behavior, and contextual information to be
        !          1620:  *        used in processing the event.
        !          1621:  * @exc:  Exception Object ref
        !          1622:  *
        !          1623:  * This method allows the dispatch of events into the implementations event
        !          1624:  * model. Events dispatched in this manner will have the same capturing and
        !          1625:  * bubbling behavior as events dispatched directly by the implementation. The
        !          1626:  * target of the event is any nodes in the subtree of the EventTarget on which
        !          1627:  * dispatchEvent is called.
        !          1628:  *
        !          1629:  * GDOME_UNSPECIFIED_EVENT_TYPE_ERR: Raised if the Event's type was not
        !          1630:  * specified by initializing the event before dispatchEvent was called.
        !          1631:  * Specification of the Event's type as %NULL or an empty string will also
        !          1632:  * trigger this exception.
        !          1633:  */
        !          1634: void
        !          1635: gdome_xml_n_subTreeDispatchEvent (GdomeNode *self, GdomeEvent *evt, GdomeException *exc)
        !          1636: {
        !          1637:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1638:   GdomeNode *child, *temp;
        !          1639: 
        !          1640:  g_return_if_fail (priv != NULL);
        !          1641:  g_return_if_fail (GDOME_XML_IS_N (priv));
        !          1642:   g_return_if_fail (evt != NULL);
        !          1643:  g_return_if_fail (exc != NULL);
        !          1644: 
        !          1645:  child = gdome_xml_n_firstChild (self, exc);
        !          1646: 
        !          1647:  while (child) {
        !          1648:    gdome_xml_n_dispatchEvent (child, evt, exc);
        !          1649:    gdome_xml_n_subTreeDispatchEvent (child, evt, exc);
        !          1650:    temp = gdome_xml_n_nextSibling (child, exc);
        !          1651:    gdome_xml_n_unref (child, exc);
        !          1652:    child = temp;
        !          1653:  }
        !          1654: }
        !          1655: 
        !          1656: /**
        !          1657:  * gdome_xml_n_canAppend:
        !          1658:  * @self:  Node Object ref
        !          1659:  * @newChild:  The Node Object ref of the node to test
        !          1660:  * @exc:  Exception Object ref
        !          1661:  *
        !          1662:  * Tests if a @newChild can be added in the child list of this node.
        !          1663:  * Returns: %TRUE if @newChild can be added, %FALSE otherwise.
        !          1664:  */
        !          1665: GdomeBoolean
        !          1666: gdome_xml_n_canAppend (GdomeNode *self, GdomeNode *newChild, GdomeException *exc)
        !          1667: {
        !          1668:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1669:  Gdome_xml_Node *new_priv = (Gdome_xml_Node *)newChild;
        !          1670:  xmlElementType new_type;
        !          1671:   GdomeBoolean ret = TRUE;
        !          1672: 
        !          1673:  g_return_val_if_fail (priv != NULL, FALSE);
        !          1674:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
        !          1675:  g_return_val_if_fail (new_priv != NULL, FALSE);
        !          1676:  g_return_val_if_fail (GDOME_XML_IS_N (new_priv), FALSE);
        !          1677:  g_return_val_if_fail (exc != NULL, FALSE);
        !          1678: 
        !          1679:   /* Check if self can have a child of newChild type */
        !          1680:   new_type = gdome_xmlGetType (new_priv->n);
        !          1681:   if (new_type == XML_DOCUMENT_FRAG_NODE)
        !          1682:    return TRUE;
        !          1683:  switch (gdome_xmlGetType (priv->n)) {
        !          1684:  case XML_DOCUMENT_TYPE_NODE:
        !          1685:   case XML_DTD_NODE:
        !          1686:  case XML_PI_NODE:
        !          1687:  case XML_COMMENT_NODE:
        !          1688:   case XML_TEXT_NODE:
        !          1689:   case XML_CDATA_SECTION_NODE:
        !          1690:   case XML_NOTATION_NODE:
        !          1691:    ret = FALSE;
        !          1692:     break;
        !          1693:  case XML_DOCUMENT_NODE:
        !          1694:     /* Element (max of one), ProcessingInstruction, Comment, DocumentType (max of one) */
        !          1695:    if ((new_type != XML_ELEMENT_NODE &&
        !          1696:         new_type != XML_PI_NODE &&
        !          1697:         new_type != XML_COMMENT_NODE &&
        !          1698:         new_type != XML_DTD_NODE &&
        !          1699:         new_type != XML_DOCUMENT_TYPE_NODE) ||
        !          1700:        (new_type == XML_ELEMENT_NODE &&
        !          1701:         xmlDocGetRootElement ((xmlDoc *)priv->n) != NULL) ||
        !          1702:        ((new_type == XML_DTD_NODE ||
        !          1703:          new_type == XML_DOCUMENT_TYPE_NODE) &&
        !          1704:         ((xmlDoc *)priv->n)->intSubset != NULL))
        !          1705:      ret = FALSE;
        !          1706:     break;
        !          1707:   case XML_DOCUMENT_FRAG_NODE:
        !          1708:   case XML_ENTITY_REF_NODE:
        !          1709:   case XML_ELEMENT_NODE:
        !          1710:   case XML_ENTITY_NODE:
        !          1711:  case XML_ENTITY_DECL:
        !          1712:    /* Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference */
        !          1713:    if (new_type != XML_ELEMENT_NODE &&
        !          1714:        new_type != XML_PI_NODE &&
        !          1715:        new_type != XML_COMMENT_NODE &&
        !          1716:        new_type != XML_TEXT_NODE &&
        !          1717:        new_type != XML_CDATA_SECTION_NODE &&
        !          1718:        new_type != XML_ENTITY_REF_NODE)
        !          1719:      ret = FALSE;
        !          1720:     break;
        !          1721:  case XML_ATTRIBUTE_NODE:
        !          1722:     /* Text, EntityReference */
        !          1723:    if (new_type != XML_TEXT_NODE &&
        !          1724:        new_type != XML_ENTITY_REF_NODE)
        !          1725:      ret = FALSE;
        !          1726:     break;
        !          1727:   default:
        !          1728:     g_warning ("gdome_xml_n_canAppend: invalid node type");
        !          1729:    ret = FALSE;
        !          1730:     break;
        !          1731:  }
        !          1732: 
        !          1733:   /* Check if newChild is an ancestor of self */
        !          1734:  if (ret) {
        !          1735:    xmlNode *p = priv->n;
        !          1736:    while (p != NULL) {
        !          1737:      if (p == new_priv->n) {
        !          1738:        ret = FALSE;
        !          1739:        break;
        !          1740:      }
        !          1741:      p = gdome_xmlGetParent (p);
        !          1742:    }
        !          1743:  }
        !          1744: 
        !          1745:   return ret;
        !          1746: }
        !          1747: 
        !          1748: /**
        !          1749:  * gdome_xml_n_eventEnabledByCode:
        !          1750:  * @self:  Node Objects ref
        !          1751:  * @code:  The event type to check
        !          1752:  *
        !          1753:  * Returns: TRUE if the specified event type is enabled
        !          1754:  */
        !          1755: GdomeBoolean
        !          1756: gdome_xml_n_eventEnabledByCode (GdomeNode *self, guint32 code)
        !          1757: {
        !          1758:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !          1759:  GdomeException exc = 0;
        !          1760:  GdomeDocument *doc;
        !          1761:  GdomeBoolean res;
        !          1762: 
        !          1763:  g_return_val_if_fail (priv != NULL, FALSE);
        !          1764:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
        !          1765: 
        !          1766:   doc = gdome_xml_doc_mkref (gdome_xmlGetOwnerOrSelf (priv->n));
        !          1767:  g_assert(doc != NULL);
        !          1768: 
        !          1769:  res = gdome_xml_doc_eventEnabledByCode (doc, code);
        !          1770: 
        !          1771:  gdome_doc_unref(doc, &exc);
        !          1772:  g_assert(exc == 0);
        !          1773: 
        !          1774:  return res;
        !          1775: }

E-mail: