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: