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

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
1.2     ! paf       107: gdome_xml_el_query_interface (xmlNode *self, const char *interface, GdomeException *exc)
1.1       paf       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 *
1.2     ! paf       160: gdome_xml_el_attributes (xmlNode *self, GdomeException *exc)
1.1       paf       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;
1.2     ! paf       230:   xmlNode *attr;
1.1       paf       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) {
1.2     ! paf       254:    if (gdome_xml_n_eventEnabledByCode((xmlNode *)self, DOM_ATTR_MODIFIED_EVENT_TYPE)) {
1.1       paf       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);
1.2     ! paf       262:      gdome_xml_n_dispatchEvent ((xmlNode *)self, (GdomeEvent *)mev, exc);
1.1       paf       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: 
1.2     ! paf       269:    if (gdome_xml_n_eventEnabledByCode((xmlNode *)self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
1.1       paf       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);
1.2     ! paf       275:      gdome_xml_n_dispatchEvent ((xmlNode *)self, (GdomeEvent *)mev, exc);
1.1       paf       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;
1.2     ! paf       305:  xmlNode *attr = NULL;
1.1       paf       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);
1.2     ! paf       400:  ret = (GdomeAttr *)gdome_xml_nnm_setNamedItem(nnm, (xmlNode *)newAttr, exc);
1.1       paf       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: 
1.2     ! paf       482:   return gdome_xml_nl_mkref ((xmlNode*)self, name, NULL, GDOME_READWRITE_NODE);
1.1       paf       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: 
1.2     ! paf       509:   return gdome_xml_nl_mkref ((xmlNode*)self, localName, namespaceURI, GDOME_READWRITE_NODE);
1.1       paf       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;
1.2     ! paf       616:    xmlNode *attr = NULL;
1.1       paf       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) {
1.2     ! paf       649:      if (gdome_xml_n_eventEnabledByCode((xmlNode *) self, DOM_ATTR_MODIFIED_EVENT_TYPE)) {
1.1       paf       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);
1.2     ! paf       657:        gdome_xml_n_dispatchEvent ((xmlNode *)self, (GdomeEvent *)mev, exc);
1.1       paf       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: 
1.2     ! paf       664:      if (gdome_xml_n_eventEnabledByCode((xmlNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
1.1       paf       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);
1.2     ! paf       670:        gdome_xml_n_dispatchEvent ((xmlNode *)self, (GdomeEvent *)mev, exc);
1.1       paf       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;
1.2     ! paf       707:  xmlNode *attr = NULL;
1.1       paf       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);
1.2     ! paf       722:  attr = (xmlNode *)gdome_xml_nnm_removeNamedItemNS(nnm, namespaceURI, localName, exc);
1.1       paf       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);
1.2     ! paf       802:  ret = (GdomeAttr *)gdome_xml_nnm_setNamedItemNS(nnm, (xmlNode *)newAttr, exc);
1.1       paf       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: