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

1.1     ! paf         1: /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
        !             2: /* gdome-xml-element.c
        !             3:  *
        !             4:  * Copyright (C) 1999 Raph Levien <raph@acm.org>
        !             5:  * Copyright (C) 2000 Mathieu Lacage <mathieu@gnu.org>
        !             6:  * Copyright (C) 2001 Paolo Casrini <paolo@casarini.org>
        !             7:  *
        !             8:  * This library is free software; you can redistribute it and/or
        !             9:  * modify it under the terms of the GNU Lesser General Public
        !            10:  * License as published by the Free Software Foundation; either
        !            11:  * version 2.1 of the License, or (at your option) any later version.
        !            12:  * 
        !            13:  * This library is distributed in the hope that it will be useful,
        !            14:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            16:  * Lesser General Public License for more details.
        !            17:  * 
        !            18:  * You should have received a copy of the GNU Lesser General Public
        !            19:  * License along with this library; if not, write to the Free Software
        !            20:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            21:  */
        !            22: 
        !            23: #include <string.h>
        !            24: #include "gdome.h"
        !            25: #include "gdome-events.h"
        !            26: #include <libxml/tree.h>
        !            27: #include <libxml/parser.h>
        !            28: #include <libxml/xmlmemory.h>
        !            29: #include <libxml/hash.h>
        !            30: #include "gdome-xml-util.h"
        !            31: #include "gdome-xml-str.h"
        !            32: #include "gdome-xml-node.h"
        !            33: #include "gdome-xml-nodel.h"
        !            34: #include "gdome-evt-event.h"
        !            35: #include "gdome-evt-mevent.h"
        !            36: #include "gdome-xml-element.h"
        !            37: #include "gdome-xml-attribute.h"
        !            38: #include "gdome-xml-nnodem.h"
        !            39: #include "gdome-xml-xmlutil.h"
        !            40: #include "gdome-xml-document.h"
        !            41: 
        !            42: 
        !            43: /* vtable for the Element */
        !            44: const GdomeElementVtab gdome_xml_el_vtab = {
        !            45:   {
        !            46:     gdome_xml_n_ref,
        !            47:     gdome_xml_n_unref,
        !            48:     gdome_xml_el_query_interface,
        !            49:     gdome_xml_n_nodeName,
        !            50:     gdome_xml_n_nodeValue,
        !            51:     gdome_xml_n_set_nodeValue,
        !            52:     gdome_xml_n_nodeType,
        !            53:     gdome_xml_n_parentNode,
        !            54:     gdome_xml_n_childNodes,
        !            55:     gdome_xml_n_firstChild,
        !            56:     gdome_xml_n_lastChild,
        !            57:     gdome_xml_n_previousSibling,
        !            58:     gdome_xml_n_nextSibling,
        !            59:     gdome_xml_el_attributes,
        !            60:     gdome_xml_n_ownerDocument,
        !            61:     gdome_xml_n_insertBefore,
        !            62:     gdome_xml_n_replaceChild,
        !            63:     gdome_xml_n_removeChild,
        !            64:     gdome_xml_n_appendChild,
        !            65:     gdome_xml_n_hasChildNodes,
        !            66:     gdome_xml_n_cloneNode,
        !            67:     gdome_xml_n_normalize,
        !            68:     gdome_xml_n_isSupported,
        !            69:     gdome_xml_n_namespaceURI,
        !            70:     gdome_xml_n_prefix,
        !            71:     gdome_xml_n_set_prefix,
        !            72:     gdome_xml_n_localName,
        !            73:     gdome_xml_n_hasAttributes,
        !            74:     gdome_xml_n_addEventListener,
        !            75:     gdome_xml_n_removeEventListener,
        !            76:     gdome_xml_n_dispatchEvent,
        !            77:     gdome_xml_n_subTreeDispatchEvent
        !            78:   },
        !            79:   gdome_xml_el_tagName,
        !            80:   gdome_xml_el_getAttribute,
        !            81:   gdome_xml_el_setAttribute,
        !            82:   gdome_xml_el_removeAttribute,
        !            83:   gdome_xml_el_getAttributeNode,
        !            84:   gdome_xml_el_setAttributeNode,
        !            85:   gdome_xml_el_removeAttributeNode,
        !            86:   gdome_xml_el_getElementsByTagName,
        !            87:   gdome_xml_el_getAttributeNS,
        !            88:   gdome_xml_el_setAttributeNS,
        !            89:   gdome_xml_el_removeAttributeNS,
        !            90:   gdome_xml_el_getAttributeNodeNS,
        !            91:   gdome_xml_el_setAttributeNodeNS,
        !            92:   gdome_xml_el_getElementsByTagNameNS,
        !            93:  gdome_xml_el_hasAttribute,
        !            94:  gdome_xml_el_hasAttributeNs
        !            95: };
        !            96: 
        !            97: /**
        !            98:  * gdome_xml_el_query_interface:
        !            99:  * @self:  Node Object ref
        !           100:  * @interface:  interface needed
        !           101:  * @exc:  Exception Object ref
        !           102:  *
        !           103:  * Returns: a reference to this object that implements the @interface needed,
        !           104:  *          or %NULL if the @interface is not supported by this Object.
        !           105:  */
        !           106: gpointer
        !           107: gdome_xml_el_query_interface (GdomeNode *self, const char *interface, GdomeException *exc)
        !           108: {
        !           109:  Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           110: 
        !           111:   g_return_val_if_fail (priv != NULL, NULL);
        !           112:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           113:   g_return_val_if_fail (interface != NULL, NULL);
        !           114:   g_return_val_if_fail (exc != NULL, NULL);
        !           115: 
        !           116:   if (!strcmp (interface, "Node") ||
        !           117:       !strcmp (interface, "Element") ||
        !           118:       !strcmp (interface, "EventTarget")) {
        !           119:     priv->refcnt++;
        !           120:     return self;
        !           121:   }
        !           122:   else
        !           123:     return NULL;
        !           124: }
        !           125: 
        !           126: /**
        !           127:  * gdome_xml_el_tagName:
        !           128:  * @self:  Element Objects ref
        !           129:  * @exc:  Exception Object ref
        !           130:  *
        !           131:  * Returns: the qualified name of the element.
        !           132:  */
        !           133: GdomeDOMString *
        !           134: gdome_xml_el_tagName (GdomeElement *self, GdomeException *exc) {
        !           135:  Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           136:   GdomeDOMString *ret = NULL;
        !           137:  
        !           138:   g_return_val_if_fail (priv != NULL, NULL);
        !           139:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           140:   g_return_val_if_fail (exc != NULL, NULL);
        !           141: 
        !           142:  if(gdome_xmlGetNs(priv->n) != NULL && gdome_xmlGetNsPrefix(priv->n) != NULL )
        !           143:    ret = gdome_xml_str_mkref_own (g_strdup_printf("%s:%s",
        !           144:                                                   (gchar *) gdome_xmlGetNsPrefix(priv->n),
        !           145:                                                   (gchar *) gdome_xmlGetName(priv->n)));
        !           146:  else
        !           147:    ret = gdome_xml_str_mkref_dup((gchar *)gdome_xmlGetName (priv->n));
        !           148: 
        !           149:  return ret;
        !           150: }
        !           151: 
        !           152: /**
        !           153:  * gdome_xml_el_attributes:
        !           154:  * @self:  Element Objects ref
        !           155:  * @exc:  Exception Object ref
        !           156:  *
        !           157:  * Returns: a NamedNodeMap of the element's attributes.
        !           158:  */
        !           159: GdomeNamedNodeMap *
        !           160: gdome_xml_el_attributes (GdomeNode *self, GdomeException *exc)
        !           161: {
        !           162:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           163: 
        !           164:   g_return_val_if_fail (priv != NULL, NULL);
        !           165:  g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           166:   g_return_val_if_fail (exc != NULL, NULL);
        !           167: 
        !           168:   return gdome_xml_nnm_mkref(gdome_xml_doc_mkref (gdome_xmlGetOwner (priv->n)),
        !           169:                              (GdomeElement *)self, gdome_xmlGetAttrList(priv->n), gdome_xmlGetNsDeclList(priv->n),
        !           170:                              priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           171: }
        !           172: 
        !           173: /**
        !           174:  * gdome_xml_el_getAttribute:
        !           175:  * @self:  Element Objects ref
        !           176:  * @name:  The name of attribute of which the value is wanted
        !           177:  * @exc:  Exception Object ref
        !           178:  *
        !           179:  * Retrieves an attribute value by name.
        !           180:  * Returns: the Attr value as a string, or the empty string if that attribute
        !           181:  * does not have a specified or default value.
        !           182:  */
        !           183: GdomeDOMString *
        !           184: gdome_xml_el_getAttribute (GdomeElement *self, GdomeDOMString *name, GdomeException *exc)
        !           185: {
        !           186:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           187:   xmlChar *value = NULL;
        !           188:  xmlNs *ns = NULL;
        !           189:  gchar **strs;
        !           190: 
        !           191:   g_return_val_if_fail (priv != NULL, NULL);
        !           192:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           193:   g_return_val_if_fail (name != NULL, NULL);
        !           194:   g_return_val_if_fail (exc != NULL, NULL);
        !           195: 
        !           196:  value = xmlGetProp (priv->n, name->str);
        !           197: 
        !           198:  if (value != NULL)
        !           199:    return gdome_xml_str_mkref_xml (value);
        !           200:  else {
        !           201:    strs = g_strsplit((gchar *)name->str, ":", 0);
        !           202:    if (xmlStrEqual(strs[0], "xmlns"))
        !           203:      ns = gdome_xmlGetNsDecl(priv->n, strs[1]);
        !           204:    g_strfreev(strs);
        !           205:    if (ns != NULL)
        !           206:      return gdome_xml_str_mkref_dup ((gchar *)ns->href);
        !           207:    else
        !           208:      return gdome_xml_str_mkref ("");
        !           209:  }
        !           210: }
        !           211: 
        !           212: /**
        !           213:  * gdome_xml_el_setAttribute:
        !           214:  * @self:  Element Objects ref
        !           215:  * @name:  The name of the attribute to create or alter
        !           216:  * @value: Value to set in string form
        !           217:  * @exc:  Exception Object ref
        !           218:  *
        !           219:  * Adds a new attribute. If an attribute with that name is already present in
        !           220:  * the element, its value is changed to be that of the value parameter.
        !           221:  *
        !           222:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           223:  */
        !           224: void
        !           225: gdome_xml_el_setAttribute (GdomeElement *self, GdomeDOMString *name, GdomeDOMString *value, GdomeException *exc)
        !           226: {
        !           227:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           228:   GdomeMutationEvent *mev;
        !           229:  GdomeDOMString *prevValue;
        !           230:   GdomeNode *attr;
        !           231: 
        !           232:   g_return_if_fail (priv != NULL);
        !           233:   g_return_if_fail (GDOME_XML_IS_EL (priv));
        !           234:   g_return_if_fail (name != NULL);
        !           235:   g_return_if_fail (value != NULL);
        !           236:   g_return_if_fail (exc != NULL);
        !           237: 
        !           238:   if (GDOME_ISREADONLY (priv)) {
        !           239:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           240:     return;
        !           241:   }
        !           242: 
        !           243:  if (!(strcmp(name->str, "xmlns"))) {
        !           244:    gdome_xmlLinkNsDecl (priv->n,
        !           245:                         NULL,
        !           246:                         (xmlChar *)value->str);
        !           247:    return;
        !           248:  }
        !           249: 
        !           250:   prevValue = gdome_xml_str_mkref_xml (xmlGetProp (priv->n, name->str));
        !           251:   attr = gdome_xml_n_mkref ((xmlNode *)xmlSetProp (priv->n, name->str, value->str));
        !           252: 
        !           253:   if (attr != NULL) {
        !           254:    if (gdome_xml_n_eventEnabledByCode((GdomeNode *)self, DOM_ATTR_MODIFIED_EVENT_TYPE)) {
        !           255:      /* Fire DOMAttrModified */
        !           256:      mev = gdome_evt_mevnt_mkref ();
        !           257:      gdome_xml_str_ref (name);
        !           258:      gdome_xml_str_ref (value);
        !           259:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_ATTR_MODIFIED_EVENT_TYPE,
        !           260:                                               TRUE, FALSE, attr,
        !           261:                                               prevValue, value, name, GDOME_MODIFICATION, exc);
        !           262:      gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           263:      gdome_xml_str_unref (value);
        !           264:      gdome_xml_str_unref (name);
        !           265:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           266:    }
        !           267:    gdome_xml_n_unref (attr, exc);
        !           268: 
        !           269:    if (gdome_xml_n_eventEnabledByCode((GdomeNode *)self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           270:      /* Fire DOMSubtreeModified */
        !           271:      mev = gdome_evt_mevnt_mkref ();
        !           272:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           273:                                               TRUE, FALSE, NULL,
        !           274:                                               NULL, NULL, NULL, 0, exc);
        !           275:      gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           276:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           277:    }
        !           278:  }
        !           279: 
        !           280:  if (prevValue != NULL)
        !           281:    gdome_xml_str_unref (prevValue);
        !           282: }
        !           283: 
        !           284: 
        !           285: /**
        !           286:  * gdome_xml_el_removeAttribute:
        !           287:  * @self:  Element Objects ref
        !           288:  * @name:  The name of the attribute to remove
        !           289:  * @exc:  Exception Object ref
        !           290:  *
        !           291:  * Removes an attribute by name. If the removed attribute is known to have a
        !           292:  * default value, an attribute immediately appears containing the default
        !           293:  * value as well as the corresponding namespace URI, local name, and prefix
        !           294:  * when applicable.
        !           295:  * To remove an attribute by local name and namespace URI, use the
        !           296:  * gdome_el_removeAttributeNS() function.
        !           297:  *
        !           298:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           299:  */
        !           300: void
        !           301: gdome_xml_el_removeAttribute (GdomeElement *self, GdomeDOMString *name, GdomeException *exc)
        !           302: {
        !           303:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           304:   GdomeNamedNodeMap *nnm = NULL;
        !           305:  GdomeNode *attr = NULL;
        !           306: 
        !           307:   g_return_if_fail (priv != NULL);
        !           308:   g_return_if_fail (GDOME_XML_IS_EL (priv));
        !           309:   g_return_if_fail (name != NULL);
        !           310:   g_return_if_fail (exc != NULL);
        !           311: 
        !           312:   if (GDOME_ISREADONLY (priv)) {
        !           313:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           314:     return;
        !           315:   }
        !           316: 
        !           317:   nnm =  gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           318:                              self, gdome_xmlGetAttrList(priv->n), NULL,
        !           319:                              priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           320:  attr = gdome_xml_nnm_removeNamedItem(nnm, name, exc);
        !           321:   gdome_xml_nnm_unref(nnm, exc);
        !           322: 
        !           323:   if (attr != NULL)
        !           324:     gdome_xml_n_unref(attr, exc);
        !           325: }
        !           326: 
        !           327: /**
        !           328:  * gdome_xml_el_getAttributeNode:
        !           329:  * @self:  Element Objects ref
        !           330:  * @name:  The name of the attribute to retreive
        !           331:  * @exc:  Exception Object ref
        !           332:  *
        !           333:  * Retrieves an attribute node by name.
        !           334:  * To retrieve an attribute node by qualified name and namespace URI, use the
        !           335:  * gdome_el_getAttributeNodeNS() method.
        !           336:  * Returns: the Attr node with the specified @name or %NULL if there is no such
        !           337:  * attribute.
        !           338:  */
        !           339: GdomeAttr *
        !           340: gdome_xml_el_getAttributeNode (GdomeElement *self, GdomeDOMString *name, GdomeException *exc)
        !           341: {
        !           342:  Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           343:  GdomeNamedNodeMap *nnm;
        !           344:   GdomeAttr *ret;
        !           345: 
        !           346:   g_return_val_if_fail (priv != NULL, NULL);
        !           347:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           348:   g_return_val_if_fail (name != NULL, NULL);
        !           349:   g_return_val_if_fail (exc != NULL, NULL);
        !           350: 
        !           351:   nnm = gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           352:                             self, gdome_xmlGetAttrList(priv->n), gdome_xmlGetNsDeclList(priv->n),
        !           353:                             priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           354:  ret = (GdomeAttr *)gdome_xml_nnm_getNamedItem(nnm, name, exc);
        !           355:  gdome_xml_nnm_unref(nnm, exc);
        !           356: 
        !           357:   return ret;
        !           358: }
        !           359: 
        !           360: /**
        !           361:  * gdome_xml_el_setAttributeNode:
        !           362:  * @self:  Element Object ref
        !           363:  * @newAttr:  The Attr node to add to the attribute list
        !           364:  * @exc:  Exception Object ref
        !           365:  *
        !           366:  * Adds a new attribute node. If an attribute with that name is already present
        !           367:  * in the element, it is replaced by the new one.
        !           368:  * To add a new attribute node with a qualified name and namespace URI, use the
        !           369:  * gdome_el_setAttributeNodeNS() method.
        !           370:  *
        !           371:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newAttr was created from a different
        !           372:  * document than the one that created the element.
        !           373:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           374:  * %GDOME_INUSE_ATTRIBUTE_ERR: Raised if @newAttr is already an attribute of
        !           375:  * another Element object. The DOM user must explicitly clone Attr nodes to
        !           376:  * re-use them in other elements.
        !           377:  * Returns: if the @newAttr attribute replaces an existing attribute, the
        !           378:  * replaced Attr node is returned, otherwise %NULL is returned.
        !           379:  */
        !           380: GdomeAttr *
        !           381: gdome_xml_el_setAttributeNode (GdomeElement *self, GdomeAttr *newAttr, GdomeException *exc)
        !           382: {
        !           383:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           384:  GdomeNamedNodeMap *nnm;
        !           385:  GdomeAttr *ret;
        !           386: 
        !           387:   g_return_val_if_fail (priv != NULL, NULL);
        !           388:  g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           389:   g_return_val_if_fail (newAttr != NULL, NULL);
        !           390:  g_return_val_if_fail (GDOME_XML_IS_A (newAttr), NULL);
        !           391:   g_return_val_if_fail (exc != NULL, NULL);
        !           392: 
        !           393:   if (GDOME_ISREADONLY (priv)) {
        !           394:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           395:     return NULL;
        !           396:   }
        !           397: 
        !           398:   nnm =  gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           399:                              self, gdome_xmlGetAttrList(priv->n), NULL, priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           400:  ret = (GdomeAttr *)gdome_xml_nnm_setNamedItem(nnm, (GdomeNode *)newAttr, exc);
        !           401:   gdome_xml_nnm_unref(nnm, exc);
        !           402: 
        !           403:  return ret;
        !           404: }
        !           405: 
        !           406: /**
        !           407:  * gdome_xml_el_removeAttributeNode:
        !           408:  * @self:  Element Objects ref
        !           409:  * @oldAttr:  The Attr node to remove from the attribute list
        !           410:  * @exc:  Exception Object ref
        !           411:  *
        !           412:  * Removes the specified attribute node. If the removed Attr has a default
        !           413:  * value it is immediately replaced. The replacing attribute has the same
        !           414:  * namespace URI and local name, as well as the original prefix, when
        !           415:  * applicable.
        !           416:  *
        !           417:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           418:  * %GDOME_NOT_FOUND_ERR: Raised if @oldAttr is not an attribute of the element.
        !           419:  * Returns: the Attr node that was removed.
        !           420:  */
        !           421: GdomeAttr *
        !           422: gdome_xml_el_removeAttributeNode (GdomeElement *self, GdomeAttr *oldAttr, GdomeException *exc)
        !           423: {
        !           424:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           425:   GdomeDOMString *localName, *namespaceURI;
        !           426:   GdomeNamedNodeMap *nnm = NULL;
        !           427:   GdomeAttr *ret = NULL;
        !           428:   xmlAttr *attr = NULL;
        !           429: 
        !           430:   g_return_val_if_fail (priv != NULL, NULL);
        !           431:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           432:   g_return_val_if_fail (oldAttr != NULL, NULL);
        !           433:  g_return_val_if_fail(GDOME_XML_IS_A (oldAttr), NULL);
        !           434:   g_return_val_if_fail (exc != NULL, NULL);
        !           435: 
        !           436:   if (GDOME_ISREADONLY (priv)) {
        !           437:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           438:     return NULL;
        !           439:   }
        !           440: 
        !           441:   attr = (xmlAttr *)((Gdome_xml_Attr *)oldAttr)->n;
        !           442:   nnm = gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           443:                             self, gdome_xmlGetAttrList(priv->n), NULL, priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           444: 
        !           445:   if (attr->ns == NULL) {
        !           446:     localName = gdome_xml_str_mkref(gdome_xmlGetName((xmlNode *)attr));
        !           447:    ret = (GdomeAttr *)gdome_xml_nnm_removeNamedItem(nnm, localName, exc);
        !           448:     gdome_xml_str_unref(localName);
        !           449:   } else {
        !           450:     localName = gdome_xml_str_mkref(gdome_xmlGetName((xmlNode *)attr));
        !           451:     namespaceURI = gdome_xml_str_mkref(gdome_xmlGetNsURI((xmlNode *)attr));
        !           452:     ret = (GdomeAttr *)gdome_xml_nnm_removeNamedItemNS(nnm, namespaceURI, localName, exc);
        !           453:     gdome_xml_str_unref(localName);
        !           454:     gdome_xml_str_unref(namespaceURI);
        !           455:   }
        !           456:  gdome_nnm_unref (nnm, exc);
        !           457: 
        !           458:   return ret;
        !           459: }
        !           460: 
        !           461: /**
        !           462:  * gdome_xml_el_getElementsByTagName:
        !           463:  * @self:  Element Objects ref
        !           464:  * @name:  The name of the tag to match on. The special value * matches all
        !           465:  *         tags.
        !           466:  * @exc:  Exception Object ref
        !           467:  *
        !           468:  * Returns: a NodeList of all descendant elements with a given tag name, in the
        !           469:  * order in which they are encountered in a preorder traversal of this Element
        !           470:  * tree.
        !           471:  */
        !           472: GdomeNodeList *
        !           473: gdome_xml_el_getElementsByTagName (GdomeElement *self, GdomeDOMString *name, GdomeException *exc)
        !           474: {
        !           475:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           476: 
        !           477:   g_return_val_if_fail (priv != NULL, NULL);
        !           478:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           479:   g_return_val_if_fail (name != NULL, NULL);
        !           480:   g_return_val_if_fail (exc != NULL, NULL);
        !           481: 
        !           482:   return gdome_xml_nl_mkref ((GdomeNode*)self, name, NULL, GDOME_READWRITE_NODE);
        !           483: }
        !           484: 
        !           485: /**
        !           486:  * gdome_xml_el_getElementsByTagNameNS:
        !           487:  * @self:  Element Objects ref
        !           488:  * @namespaceURI:  The namespace URI of the elements to match on. The special
        !           489:  *              value * matches all namespaces.
        !           490:  * @localName:  The local name of the elements to match on. The special value
        !           491:  *              * matches all local names.
        !           492:  * @exc:  Exception Object ref
        !           493:  *
        !           494:  * Returns: a NodeList of all the descendant elements with a given local name
        !           495:  * and namespace URI in the order in which they are encountered in a preorder
        !           496:  * traversal of this Element tree.
        !           497:  */
        !           498: GdomeNodeList *
        !           499: gdome_xml_el_getElementsByTagNameNS (GdomeElement *self, GdomeDOMString *namespaceURI, GdomeDOMString *localName, GdomeException *exc)
        !           500: {
        !           501:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           502: 
        !           503:   g_return_val_if_fail (priv != NULL, NULL);
        !           504:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           505:   g_return_val_if_fail (namespaceURI != NULL, NULL);
        !           506:   g_return_val_if_fail (localName != NULL, NULL);
        !           507:   g_return_val_if_fail (exc != NULL, NULL);
        !           508: 
        !           509:   return gdome_xml_nl_mkref ((GdomeNode*)self, localName, namespaceURI, GDOME_READWRITE_NODE);
        !           510: }
        !           511: 
        !           512: /**
        !           513:  * gdome_xml_el_getAttributeNS:
        !           514:  * @self:  Element Objects ref
        !           515:  * @namespaceURI:  The namespaceURI of attribute to retrieve
        !           516:  * @localName:  The localName of the attribute to retrieve
        !           517:  * @exc:  Exception Object ref
        !           518:  *
        !           519:  * Retrieves an attribute value by local name and namespace URI.
        !           520:  * Returns: the Attr value as a string, or the empty string if that attribute
        !           521:  * does not have a specified or default value.
        !           522:  */
        !           523: GdomeDOMString *
        !           524: gdome_xml_el_getAttributeNS (GdomeElement *self, GdomeDOMString *namespaceURI, GdomeDOMString *localName, GdomeException *exc)
        !           525: {
        !           526:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           527:   xmlChar *value = NULL;
        !           528:  xmlNs *ns = NULL;
        !           529: 
        !           530:   g_return_val_if_fail (priv != NULL, NULL);
        !           531:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           532:   g_return_val_if_fail (namespaceURI != NULL, NULL);
        !           533:   g_return_val_if_fail (localName != NULL, NULL);
        !           534:   g_return_val_if_fail (exc != NULL, NULL);
        !           535: 
        !           536:  value = xmlGetNsProp (priv->n, localName->str, namespaceURI->str);
        !           537: 
        !           538:  if (value != NULL)
        !           539:    return gdome_xml_str_mkref_xml (value);
        !           540:  else if (xmlStrEqual(namespaceURI->str, GDOME_XMLNS_NAMESPACE)) {
        !           541:    ns = gdome_xmlGetNsDecl(priv->n, localName->str);
        !           542:    if (ns != NULL)
        !           543:      return gdome_xml_str_mkref_dup ((gchar *)ns->href);
        !           544:    else
        !           545:      return gdome_xml_str_mkref ("");
        !           546:  } else {
        !           547:    return gdome_xml_str_mkref ("");
        !           548:  }
        !           549: }
        !           550: 
        !           551: /**
        !           552:  * gdome_xml_el_setAttributeNS:
        !           553:  * @self:  Element Objects ref
        !           554:  * @namespaceURI:  The namespace URI of attribute to create or alter
        !           555:  * @qualifiedName:  The qualifiedName of the attribute to create or alter
        !           556:  * @value: Value to set in string form
        !           557:  * @exc:  Exception Object ref
        !           558:  *
        !           559:  * Adds a new attribute. If an attribute with the same @namespaceURI and
        !           560:  * localName is already present in the element, its value is changed to be
        !           561:  * that of the value parameter.
        !           562:  *
        !           563:  * %GDOME_NAMESPACE_ERR: Raised if the @qualifiedName is malformed, if the
        !           564:  * @qualifiedName has a prefix and the @namespaceURI is %NULL, if the
        !           565:  * @qualifiedName has a prefix that is "xml" and the @namespaceURI is different
        !           566:  * from "http://www.w3.org/XML/1998/namespace", or if the @qualifiedName is
        !           567:  * "xmlns" and the namespaceURI is different from "http://www.w3.org/2000/xmlns/".
        !           568:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           569:  */
        !           570: void
        !           571: gdome_xml_el_setAttributeNS (GdomeElement *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeDOMString *value, GdomeException *exc)
        !           572: {
        !           573:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           574:   gchar **strs;
        !           575:   gchar *prefix = NULL;
        !           576:   gchar *localName = NULL;
        !           577:  xmlNs *ns = NULL;
        !           578: 
        !           579:   g_return_if_fail (priv != NULL);
        !           580:   g_return_if_fail (GDOME_XML_IS_EL (priv));
        !           581:   g_return_if_fail (namespaceURI != NULL);
        !           582:   g_return_if_fail (qualifiedName != NULL);
        !           583:   g_return_if_fail (value != NULL);
        !           584:   g_return_if_fail (exc != NULL);
        !           585: 
        !           586:   if (GDOME_ISREADONLY (priv)) {
        !           587:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           588:     return;
        !           589:   }
        !           590: 
        !           591:  /* test malformed qualifiedName */
        !           592:  strs = g_strsplit((gchar *)qualifiedName->str, ":", 0);
        !           593:   if (strs[0] && strs[1] && !strs[2]) {              /* there's only one ':' */
        !           594:     if (namespaceURI == NULL) {
        !           595:       *exc = GDOME_NAMESPACE_ERR;
        !           596:     } else {
        !           597:       prefix = g_strdup(strs[0]);
        !           598:       localName = g_strdup(strs[1]);
        !           599:       if ((!strcmp (prefix, "xml") && strcmp(namespaceURI->str, "http://www.w3.org/XML/1998/namespace"))) {
        !           600:         *exc = GDOME_NAMESPACE_ERR;
        !           601:       }
        !           602:     }
        !           603:   } else if (!strs[1] && namespaceURI != NULL) {     /* there's no ':' */
        !           604:     prefix = g_strdup("");
        !           605:     localName = g_strdup(strs[0]);
        !           606:     if (strcmp (localName, "xmlns"))
        !           607:       *exc = GDOME_NAMESPACE_ERR;
        !           608:   } else if (strs[0] && strs[1] && strs[2]) {        /* there are more than one ':' */
        !           609:     *exc = GDOME_NAMESPACE_ERR;
        !           610:  }
        !           611:  g_strfreev(strs);
        !           612: 
        !           613:  if (!*exc) {
        !           614:    GdomeMutationEvent *mev;
        !           615:    GdomeDOMString *prevValue = NULL;
        !           616:    GdomeNode *attr = NULL;
        !           617: 
        !           618:     if (localName != NULL) {
        !           619:      if (!(strcmp(prefix, "xmlns"))) {
        !           620:        /* BUG 1001 need to set attr and prevValue so events are fired */
        !           621:        gdome_xmlLinkNsDecl (priv->n,
        !           622:                             (xmlChar *)localName,
        !           623:                             (xmlChar *)value->str);
        !           624:      } else {
        !           625:        xmlDoc * doc = gdome_xmlGetOwner(priv->n);
        !           626:        ns = xmlSearchNsByHref (doc, priv->n, (xmlChar *)namespaceURI->str);
        !           627:        if(ns == NULL || !xmlStrEqual((xmlChar *)prefix, ns->prefix)) {
        !           628:          ns = gdome_xmlNewNs (doc, namespaceURI->str, prefix);
        !           629:        }
        !           630:        prevValue = gdome_xml_str_mkref_own (xmlGetNsProp (priv->n,
        !           631:                                                           (xmlChar *)localName,
        !           632:                                                           (xmlChar *)namespaceURI->str));
        !           633:        attr = gdome_xml_n_mkref ((xmlNode *)xmlSetNsProp(priv->n, ns,
        !           634:                                                          (xmlChar *)localName,
        !           635:                                                          (xmlChar *)value->str));
        !           636:      }
        !           637:      g_free(prefix);
        !           638:      g_free(localName);
        !           639:    }
        !           640:    else {
        !           641:      prevValue = gdome_xml_str_mkref_xml (xmlGetProp (priv->n,
        !           642:                                                       (xmlChar *)qualifiedName->str));
        !           643:      attr = gdome_xml_n_mkref ((xmlNode *)xmlSetProp (priv->n,
        !           644:                                                       (xmlChar *)qualifiedName->str,
        !           645:                                                       (xmlChar *)value->str));
        !           646:    }
        !           647: 
        !           648:    if (attr != NULL) {
        !           649:      if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_ATTR_MODIFIED_EVENT_TYPE)) {
        !           650:        /* Fire DOMAttrModified */
        !           651:        mev = gdome_evt_mevnt_mkref ();
        !           652:        gdome_xml_str_ref (qualifiedName);
        !           653:        gdome_xml_str_ref (value);
        !           654:        gdome_evt_mevnt_initMutationEventByCode (mev, DOM_ATTR_MODIFIED_EVENT_TYPE,
        !           655:                                                 TRUE, FALSE, attr,
        !           656:                                                 prevValue, value, qualifiedName, GDOME_MODIFICATION, exc);
        !           657:        gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           658:        gdome_xml_str_unref (value);
        !           659:        gdome_xml_str_unref (qualifiedName);
        !           660:        gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           661:      }
        !           662:      gdome_xml_n_unref (attr, exc);
        !           663: 
        !           664:      if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
        !           665:        /* Fire DOMSubtreeModified */
        !           666:        mev = gdome_evt_mevnt_mkref ();
        !           667:        gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
        !           668:                                                 TRUE, FALSE, NULL,
        !           669:                                                 NULL, NULL, NULL, 0, exc);
        !           670:        gdome_xml_n_dispatchEvent ((GdomeNode *)self, (GdomeEvent *)mev, exc);
        !           671:        gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
        !           672:      }
        !           673:    }
        !           674: 
        !           675:    if (prevValue != NULL)
        !           676:      gdome_xml_str_unref (prevValue);
        !           677:  }
        !           678:  else {
        !           679:    if (localName != NULL) {
        !           680:      g_free (prefix);
        !           681:      g_free (localName);
        !           682:    }
        !           683: 
        !           684:    return;
        !           685:   }
        !           686: }
        !           687: 
        !           688: /**
        !           689:  * gdome_xml_el_removeAttributeNS:
        !           690:  * @self:  Element Objects ref
        !           691:  * @namespaceURI:  The namespaceURI of attribute to remove
        !           692:  * @localName:  The localName of the attribute to remove
        !           693:  * @exc:  Exception Object ref
        !           694:  *
        !           695:  * Removes an attribute by local name and namespace URI. If the removed
        !           696:  * attribute has a default value it is immediately replaced. The replacing
        !           697:  * attribute has the same namespace URI and local name, as well as the
        !           698:  * original prefix.
        !           699:  *
        !           700:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           701:  */
        !           702: void
        !           703: gdome_xml_el_removeAttributeNS (GdomeElement *self, GdomeDOMString *namespaceURI, GdomeDOMString *localName, GdomeException *exc)
        !           704: {
        !           705:   Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           706:  GdomeNamedNodeMap *nnm = NULL;
        !           707:  GdomeNode *attr = NULL;
        !           708: 
        !           709:   g_return_if_fail (priv != NULL);
        !           710:   g_return_if_fail (GDOME_XML_IS_EL (priv));
        !           711:   g_return_if_fail (namespaceURI != NULL);
        !           712:   g_return_if_fail (localName != NULL);
        !           713:   g_return_if_fail (exc != NULL);
        !           714: 
        !           715:   if (GDOME_ISREADONLY (priv)) {
        !           716:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           717:     return;
        !           718:   }
        !           719: 
        !           720:   nnm =  gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           721:                              self, gdome_xmlGetAttrList(priv->n), NULL, priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           722:  attr = (GdomeNode *)gdome_xml_nnm_removeNamedItemNS(nnm, namespaceURI, localName, exc);
        !           723:   gdome_xml_nnm_unref(nnm, exc);
        !           724: 
        !           725:  if (attr != NULL)
        !           726:     gdome_xml_n_unref(attr, exc);
        !           727: }
        !           728: 
        !           729: /**
        !           730:  * gdome_xml_el_getAttributeNodeNS:
        !           731:  * @self:  Element Objects ref
        !           732:  * @namespaceURI:  The namespace URI of the attribute to retrieve.
        !           733:  * @localName:  The local name of the attribute to retrieve.
        !           734:  * @exc:  Exception Object ref
        !           735:  *
        !           736:  * Retrieves an Attr node by local name and namespace URI.
        !           737:  * Returns: the Attr node with the specified attribute local name and
        !           738:  * namespace URI or %NULL if there is no such attribute.
        !           739:  */
        !           740: GdomeAttr *
        !           741: gdome_xml_el_getAttributeNodeNS (GdomeElement *self, GdomeDOMString *namespaceURI, GdomeDOMString *localName, GdomeException *exc)
        !           742: {
        !           743:  Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           744:  GdomeNamedNodeMap *nnm;
        !           745:   GdomeAttr *ret;
        !           746: 
        !           747:   g_return_val_if_fail (priv != NULL, NULL);
        !           748:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), NULL);
        !           749:   g_return_val_if_fail (namespaceURI != NULL, NULL);
        !           750:   g_return_val_if_fail (localName != NULL, NULL);
        !           751:   g_return_val_if_fail (exc != NULL, NULL);
        !           752: 
        !           753:   nnm = gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           754:                             self, gdome_xmlGetAttrList(priv->n), gdome_xmlGetNsDeclList(priv->n),
        !           755:                             priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           756:  ret = (GdomeAttr *)gdome_xml_nnm_getNamedItemNS(nnm, namespaceURI, localName, exc);
        !           757:  gdome_xml_nnm_unref(nnm, exc);
        !           758: 
        !           759:   return ret;
        !           760: }
        !           761: 
        !           762: /**
        !           763:  * gdome_xml_el_setAttributeNodeNS:
        !           764:  * @self:  Element Object ref
        !           765:  * @newAttr:  The Attr node to add to the attribute list
        !           766:  * @exc:  Exception Object ref
        !           767:  *
        !           768:  * Adds a new attribute. If an attribute with that local name and that
        !           769:  * namespace URI is already present in the element, it is replaced by the new
        !           770:  * one.
        !           771:  *
        !           772:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newAttr was created from a different
        !           773:  * document than the one that created the element.
        !           774:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
        !           775:  * %GDOME_INUSE_ATTRIBUTE_ERR: Raised if @newAttr is already an attribute of
        !           776:  * another Element object. The DOM user must explicitly clone Attr nodes to
        !           777:  * re-use them in other elements.
        !           778:  * Returns: if the @newAttr attribute replaces an existing attribute with the
        !           779:  * same local name and namespace URI, the replaced Attr node is returned,
        !           780:  * otherwise %NULL is returned.
        !           781:  */
        !           782: GdomeAttr *
        !           783: gdome_xml_el_setAttributeNodeNS (GdomeElement *self, GdomeAttr *newAttr, GdomeException *exc)
        !           784: {
        !           785:  Gdome_xml_Element *priv = (Gdome_xml_Element *)self;
        !           786:  GdomeNamedNodeMap *nnm;
        !           787:  GdomeAttr *ret;
        !           788: 
        !           789:   g_return_val_if_fail (priv != NULL, NULL);
        !           790:  g_return_val_if_fail(GDOME_XML_IS_EL (priv), NULL);
        !           791:   g_return_val_if_fail (newAttr != NULL, NULL);
        !           792:  g_return_val_if_fail(GDOME_XML_IS_A (newAttr), NULL);
        !           793:   g_return_val_if_fail (exc != NULL, NULL);
        !           794: 
        !           795:   if (GDOME_ISREADONLY (priv)) {
        !           796:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
        !           797:     return NULL;
        !           798:   }
        !           799: 
        !           800:   nnm =  gdome_xml_nnm_mkref((GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n)),
        !           801:                              self, gdome_xmlGetAttrList(priv->n), NULL, priv->accessType, GDOME_ATTRIBUTE_NODE);
        !           802:  ret = (GdomeAttr *)gdome_xml_nnm_setNamedItemNS(nnm, (GdomeNode *)newAttr, exc);
        !           803:  gdome_xml_nnm_unref(nnm, exc);
        !           804: 
        !           805:  return ret;
        !           806: }
        !           807: 
        !           808: /**
        !           809:  * gdome_xml_el_hasAttribute:
        !           810:  * @self:  Element Objects ref
        !           811:  * @name:  The name of the attribute to look for.
        !           812:  * @exc:  Exception Object ref
        !           813:  *
        !           814:  * Returns: %TRUE when an attribute with a given name is specified on this
        !           815:  * element or has a default value, %FALSE otherwise.
        !           816:  */
        !           817: GdomeBoolean
        !           818: gdome_xml_el_hasAttribute (GdomeElement *self, GdomeDOMString *name, GdomeException *exc)
        !           819: {
        !           820:   Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           821:  xmlChar *val = NULL;
        !           822:  xmlNs *ns = NULL;
        !           823:  gchar **strs = NULL;
        !           824: 
        !           825:   g_return_val_if_fail (priv != NULL, 0);
        !           826:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), 0);
        !           827:   g_return_val_if_fail (name != NULL, 0);
        !           828:   g_return_val_if_fail (exc != NULL, 0);
        !           829: 
        !           830:   val = xmlGetProp (priv->n, name->str);
        !           831: 
        !           832:   if (val != NULL) {
        !           833:     xmlFree(val);
        !           834:    return 1;
        !           835:  } else {
        !           836:    strs = g_strsplit((gchar *)name->str, ":", 0);
        !           837:    if (xmlStrEqual(strs[0], "xmlns"))
        !           838:      ns = gdome_xmlGetNsDecl(priv->n, strs[1]);
        !           839:    g_strfreev(strs);
        !           840:    if (ns != NULL)
        !           841:      return 1;
        !           842:    else
        !           843:      return 0;
        !           844:  }
        !           845: }
        !           846: 
        !           847: /**
        !           848:  * gdome_xml_el_hasAttributeNS:
        !           849:  * @self:  Element Objects ref
        !           850:  * @namespaceURI:  The namespaceURI of the attribute to look for.
        !           851:  * @localName:  The localName of the attribute to look for.
        !           852:  * @exc:  Exception Object ref
        !           853:  *
        !           854:  * Returns: %TRUE when an attribute with a given local name and namespace URI
        !           855:  * is specified on this element or has a default value, %FALSE otherwise.
        !           856:  */
        !           857: GdomeBoolean         
        !           858: gdome_xml_el_hasAttributeNs (GdomeElement *self, GdomeDOMString *namespaceURI, GdomeDOMString *localName, GdomeException *exc)
        !           859: {
        !           860:   Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
        !           861:  xmlChar *val;
        !           862:  xmlNs *ns;
        !           863: 
        !           864:   g_return_val_if_fail (priv != NULL, 0);
        !           865:   g_return_val_if_fail (GDOME_XML_IS_EL (priv), 0);
        !           866:   g_return_val_if_fail (namespaceURI != NULL, 0);
        !           867:   g_return_val_if_fail (localName != NULL, 0);
        !           868:   g_return_val_if_fail (exc != NULL, 0);
        !           869: 
        !           870:  val = xmlGetNsProp (priv->n, localName->str, namespaceURI->str);
        !           871: 
        !           872:  if (val != NULL) {
        !           873:     xmlFree(val);
        !           874:    return 1;
        !           875:  } else if (xmlStrEqual(namespaceURI->str, GDOME_XMLNS_NAMESPACE)) {
        !           876:    ns = gdome_xmlGetNsDecl(priv->n, localName->str);
        !           877:    if (ns != NULL)
        !           878:      return 1;
        !           879:    else
        !           880:      return 0;
        !           881:  } else {
        !           882:    return 0;
        !           883:  }
        !           884: }
        !           885: 

E-mail: