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: