1 /* 2 * DOM Attribute implementation 3 * 4 * Copyright 2006 Huw Davies 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 # include <libxml/HTMLtree.h> 30 #endif 31 32 #include "windef.h" 33 #include "winbase.h" 34 #include "winuser.h" 35 #include "ole2.h" 36 #include "msxml6.h" 37 38 #include "msxml_private.h" 39 40 #include "wine/debug.h" 41 42 #ifdef HAVE_LIBXML2 43 44 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 45 46 static const xmlChar xmlns[] = "xmlns"; 47 48 typedef struct _domattr 49 { 50 xmlnode node; 51 IXMLDOMAttribute IXMLDOMAttribute_iface; 52 LONG ref; 53 } domattr; 54 55 static const tid_t domattr_se_tids[] = { 56 IXMLDOMNode_tid, 57 IXMLDOMAttribute_tid, 58 NULL_tid 59 }; 60 61 static inline domattr *impl_from_IXMLDOMAttribute( IXMLDOMAttribute *iface ) 62 { 63 return CONTAINING_RECORD(iface, domattr, IXMLDOMAttribute_iface); 64 } 65 66 static HRESULT WINAPI domattr_QueryInterface( 67 IXMLDOMAttribute *iface, 68 REFIID riid, 69 void** ppvObject ) 70 { 71 domattr *This = impl_from_IXMLDOMAttribute( iface ); 72 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); 73 74 if ( IsEqualGUID( riid, &IID_IXMLDOMAttribute ) || 75 IsEqualGUID( riid, &IID_IXMLDOMNode ) || 76 IsEqualGUID( riid, &IID_IDispatch ) || 77 IsEqualGUID( riid, &IID_IUnknown ) ) 78 { 79 *ppvObject = iface; 80 } 81 else if(node_query_interface(&This->node, riid, ppvObject)) 82 { 83 return *ppvObject ? S_OK : E_NOINTERFACE; 84 } 85 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) 86 { 87 return node_create_supporterrorinfo(domattr_se_tids, ppvObject); 88 } 89 else 90 { 91 TRACE("Unsupported interface %s\n", debugstr_guid(riid)); 92 *ppvObject = NULL; 93 return E_NOINTERFACE; 94 } 95 96 IXMLDOMAttribute_AddRef(iface); 97 return S_OK; 98 } 99 100 static ULONG WINAPI domattr_AddRef( 101 IXMLDOMAttribute *iface ) 102 { 103 domattr *This = impl_from_IXMLDOMAttribute( iface ); 104 ULONG ref = InterlockedIncrement( &This->ref ); 105 TRACE("(%p)->(%d)\n", This, ref); 106 return ref; 107 } 108 109 static ULONG WINAPI domattr_Release( 110 IXMLDOMAttribute *iface ) 111 { 112 domattr *This = impl_from_IXMLDOMAttribute( iface ); 113 ULONG ref = InterlockedDecrement( &This->ref ); 114 115 TRACE("(%p)->(%d)\n", This, ref); 116 if ( ref == 0 ) 117 { 118 destroy_xmlnode(&This->node); 119 heap_free( This ); 120 } 121 122 return ref; 123 } 124 125 static HRESULT WINAPI domattr_GetTypeInfoCount( 126 IXMLDOMAttribute *iface, 127 UINT* pctinfo ) 128 { 129 domattr *This = impl_from_IXMLDOMAttribute( iface ); 130 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); 131 } 132 133 static HRESULT WINAPI domattr_GetTypeInfo( 134 IXMLDOMAttribute *iface, 135 UINT iTInfo, LCID lcid, 136 ITypeInfo** ppTInfo ) 137 { 138 domattr *This = impl_from_IXMLDOMAttribute( iface ); 139 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, 140 iTInfo, lcid, ppTInfo); 141 } 142 143 static HRESULT WINAPI domattr_GetIDsOfNames( 144 IXMLDOMAttribute *iface, 145 REFIID riid, LPOLESTR* rgszNames, 146 UINT cNames, LCID lcid, DISPID* rgDispId ) 147 { 148 domattr *This = impl_from_IXMLDOMAttribute( iface ); 149 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, 150 riid, rgszNames, cNames, lcid, rgDispId); 151 } 152 153 static HRESULT WINAPI domattr_Invoke( 154 IXMLDOMAttribute *iface, 155 DISPID dispIdMember, REFIID riid, LCID lcid, 156 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, 157 EXCEPINFO* pExcepInfo, UINT* puArgErr ) 158 { 159 domattr *This = impl_from_IXMLDOMAttribute( iface ); 160 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, 161 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 162 } 163 164 static HRESULT WINAPI domattr_get_nodeName( 165 IXMLDOMAttribute *iface, 166 BSTR* p ) 167 { 168 domattr *This = impl_from_IXMLDOMAttribute( iface ); 169 170 TRACE("(%p)->(%p)\n", This, p); 171 172 return node_get_nodeName(&This->node, p); 173 } 174 175 static HRESULT WINAPI domattr_get_nodeValue( 176 IXMLDOMAttribute *iface, 177 VARIANT* value) 178 { 179 domattr *This = impl_from_IXMLDOMAttribute( iface ); 180 181 TRACE("(%p)->(%p)\n", This, value); 182 183 return node_get_content(&This->node, value); 184 } 185 186 static HRESULT WINAPI domattr_put_nodeValue( 187 IXMLDOMAttribute *iface, 188 VARIANT value) 189 { 190 domattr *This = impl_from_IXMLDOMAttribute( iface ); 191 192 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); 193 194 return node_put_value_escaped(&This->node, &value); 195 } 196 197 static HRESULT WINAPI domattr_get_nodeType( 198 IXMLDOMAttribute *iface, 199 DOMNodeType* domNodeType ) 200 { 201 domattr *This = impl_from_IXMLDOMAttribute( iface ); 202 203 TRACE("(%p)->(%p)\n", This, domNodeType); 204 205 *domNodeType = NODE_ATTRIBUTE; 206 return S_OK; 207 } 208 209 static HRESULT WINAPI domattr_get_parentNode( 210 IXMLDOMAttribute *iface, 211 IXMLDOMNode** parent ) 212 { 213 domattr *This = impl_from_IXMLDOMAttribute( iface ); 214 TRACE("(%p)->(%p)\n", This, parent); 215 if (!parent) return E_INVALIDARG; 216 *parent = NULL; 217 return S_FALSE; 218 } 219 220 static HRESULT WINAPI domattr_get_childNodes( 221 IXMLDOMAttribute *iface, 222 IXMLDOMNodeList** outList) 223 { 224 domattr *This = impl_from_IXMLDOMAttribute( iface ); 225 226 TRACE("(%p)->(%p)\n", This, outList); 227 228 return node_get_child_nodes(&This->node, outList); 229 } 230 231 static HRESULT WINAPI domattr_get_firstChild( 232 IXMLDOMAttribute *iface, 233 IXMLDOMNode** domNode) 234 { 235 domattr *This = impl_from_IXMLDOMAttribute( iface ); 236 237 TRACE("(%p)->(%p)\n", This, domNode); 238 239 return node_get_first_child(&This->node, domNode); 240 } 241 242 static HRESULT WINAPI domattr_get_lastChild( 243 IXMLDOMAttribute *iface, 244 IXMLDOMNode** domNode) 245 { 246 domattr *This = impl_from_IXMLDOMAttribute( iface ); 247 248 TRACE("(%p)->(%p)\n", This, domNode); 249 250 return node_get_last_child(&This->node, domNode); 251 } 252 253 static HRESULT WINAPI domattr_get_previousSibling( 254 IXMLDOMAttribute *iface, 255 IXMLDOMNode** domNode) 256 { 257 domattr *This = impl_from_IXMLDOMAttribute( iface ); 258 259 TRACE("(%p)->(%p)\n", This, domNode); 260 261 return return_null_node(domNode); 262 } 263 264 static HRESULT WINAPI domattr_get_nextSibling( 265 IXMLDOMAttribute *iface, 266 IXMLDOMNode** domNode) 267 { 268 domattr *This = impl_from_IXMLDOMAttribute( iface ); 269 270 TRACE("(%p)->(%p)\n", This, domNode); 271 272 return return_null_node(domNode); 273 } 274 275 static HRESULT WINAPI domattr_get_attributes( 276 IXMLDOMAttribute *iface, 277 IXMLDOMNamedNodeMap** attributeMap) 278 { 279 domattr *This = impl_from_IXMLDOMAttribute( iface ); 280 281 TRACE("(%p)->(%p)\n", This, attributeMap); 282 283 return return_null_ptr((void**)attributeMap); 284 } 285 286 static HRESULT WINAPI domattr_insertBefore( 287 IXMLDOMAttribute *iface, 288 IXMLDOMNode* newNode, VARIANT refChild, 289 IXMLDOMNode** old_node) 290 { 291 domattr *This = impl_from_IXMLDOMAttribute( iface ); 292 DOMNodeType type; 293 HRESULT hr; 294 295 FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), old_node); 296 297 if (!newNode) return E_INVALIDARG; 298 299 hr = IXMLDOMNode_get_nodeType(newNode, &type); 300 if (hr != S_OK) return hr; 301 302 TRACE("new node type %d\n", type); 303 switch (type) 304 { 305 case NODE_ATTRIBUTE: 306 case NODE_CDATA_SECTION: 307 case NODE_COMMENT: 308 case NODE_ELEMENT: 309 case NODE_PROCESSING_INSTRUCTION: 310 if (old_node) *old_node = NULL; 311 return E_FAIL; 312 default: 313 return node_insert_before(&This->node, newNode, &refChild, old_node); 314 } 315 } 316 317 static HRESULT WINAPI domattr_replaceChild( 318 IXMLDOMAttribute *iface, 319 IXMLDOMNode* newNode, 320 IXMLDOMNode* oldNode, 321 IXMLDOMNode** outOldNode) 322 { 323 domattr *This = impl_from_IXMLDOMAttribute( iface ); 324 325 FIXME("(%p)->(%p %p %p) needs tests\n", This, newNode, oldNode, outOldNode); 326 327 return node_replace_child(&This->node, newNode, oldNode, outOldNode); 328 } 329 330 static HRESULT WINAPI domattr_removeChild( 331 IXMLDOMAttribute *iface, 332 IXMLDOMNode *child, IXMLDOMNode **oldChild) 333 { 334 domattr *This = impl_from_IXMLDOMAttribute( iface ); 335 TRACE("(%p)->(%p %p)\n", This, child, oldChild); 336 return node_remove_child(&This->node, child, oldChild); 337 } 338 339 static HRESULT WINAPI domattr_appendChild( 340 IXMLDOMAttribute *iface, 341 IXMLDOMNode *child, IXMLDOMNode **outChild) 342 { 343 domattr *This = impl_from_IXMLDOMAttribute( iface ); 344 TRACE("(%p)->(%p %p)\n", This, child, outChild); 345 return node_append_child(&This->node, child, outChild); 346 } 347 348 static HRESULT WINAPI domattr_hasChildNodes( 349 IXMLDOMAttribute *iface, 350 VARIANT_BOOL *ret) 351 { 352 domattr *This = impl_from_IXMLDOMAttribute( iface ); 353 TRACE("(%p)->(%p)\n", This, ret); 354 return node_has_childnodes(&This->node, ret); 355 } 356 357 static HRESULT WINAPI domattr_get_ownerDocument( 358 IXMLDOMAttribute *iface, 359 IXMLDOMDocument **doc) 360 { 361 domattr *This = impl_from_IXMLDOMAttribute( iface ); 362 TRACE("(%p)->(%p)\n", This, doc); 363 return node_get_owner_doc(&This->node, doc); 364 } 365 366 static HRESULT WINAPI domattr_cloneNode( 367 IXMLDOMAttribute *iface, 368 VARIANT_BOOL deep, IXMLDOMNode** outNode) 369 { 370 domattr *This = impl_from_IXMLDOMAttribute( iface ); 371 TRACE("(%p)->(%d %p)\n", This, deep, outNode); 372 return node_clone( &This->node, deep, outNode ); 373 } 374 375 static HRESULT WINAPI domattr_get_nodeTypeString( 376 IXMLDOMAttribute *iface, 377 BSTR* p) 378 { 379 domattr *This = impl_from_IXMLDOMAttribute( iface ); 380 static const WCHAR attributeW[] = {'a','t','t','r','i','b','u','t','e',0}; 381 382 TRACE("(%p)->(%p)\n", This, p); 383 384 return return_bstr(attributeW, p); 385 } 386 387 static HRESULT WINAPI domattr_get_text( 388 IXMLDOMAttribute *iface, 389 BSTR* p) 390 { 391 domattr *This = impl_from_IXMLDOMAttribute( iface ); 392 TRACE("(%p)->(%p)\n", This, p); 393 return node_get_text(&This->node, p); 394 } 395 396 static HRESULT WINAPI domattr_put_text( 397 IXMLDOMAttribute *iface, 398 BSTR p) 399 { 400 domattr *This = impl_from_IXMLDOMAttribute( iface ); 401 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 402 return node_put_text( &This->node, p ); 403 } 404 405 static HRESULT WINAPI domattr_get_specified( 406 IXMLDOMAttribute *iface, 407 VARIANT_BOOL* isSpecified) 408 { 409 domattr *This = impl_from_IXMLDOMAttribute( iface ); 410 FIXME("(%p)->(%p) stub!\n", This, isSpecified); 411 *isSpecified = VARIANT_TRUE; 412 return S_OK; 413 } 414 415 static HRESULT WINAPI domattr_get_definition( 416 IXMLDOMAttribute *iface, 417 IXMLDOMNode** definitionNode) 418 { 419 domattr *This = impl_from_IXMLDOMAttribute( iface ); 420 FIXME("(%p)->(%p)\n", This, definitionNode); 421 return E_NOTIMPL; 422 } 423 424 static HRESULT WINAPI domattr_get_nodeTypedValue( 425 IXMLDOMAttribute *iface, 426 VARIANT* value) 427 { 428 domattr *This = impl_from_IXMLDOMAttribute( iface ); 429 IXMLDOMDocument *doc; 430 HRESULT hr; 431 432 TRACE("(%p)->(%p)\n", This, value); 433 434 hr = IXMLDOMAttribute_get_ownerDocument(iface, &doc); 435 if (hr == S_OK) 436 { 437 IXMLDOMDocument3 *doc3; 438 439 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMDocument3, (void**)&doc3); 440 IXMLDOMDocument_Release(doc); 441 442 if (hr == S_OK) 443 { 444 VARIANT schemas; 445 446 hr = IXMLDOMDocument3_get_schemas(doc3, &schemas); 447 IXMLDOMDocument3_Release(doc3); 448 449 if (hr != S_OK) 450 return IXMLDOMAttribute_get_value(iface, value); 451 else 452 { 453 FIXME("need to query schema for attribute type\n"); 454 VariantClear(&schemas); 455 } 456 } 457 } 458 459 return return_null_var(value); 460 } 461 462 static HRESULT WINAPI domattr_put_nodeTypedValue( 463 IXMLDOMAttribute *iface, 464 VARIANT typedValue) 465 { 466 domattr *This = impl_from_IXMLDOMAttribute( iface ); 467 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); 468 return E_NOTIMPL; 469 } 470 471 static HRESULT WINAPI domattr_get_dataType( 472 IXMLDOMAttribute *iface, 473 VARIANT* typename) 474 { 475 domattr *This = impl_from_IXMLDOMAttribute( iface ); 476 TRACE("(%p)->(%p)\n", This, typename); 477 return return_null_var( typename ); 478 } 479 480 static HRESULT WINAPI domattr_put_dataType( 481 IXMLDOMAttribute *iface, 482 BSTR p) 483 { 484 domattr *This = impl_from_IXMLDOMAttribute( iface ); 485 486 FIXME("(%p)->(%s)\n", This, debugstr_w(p)); 487 488 if(!p) 489 return E_INVALIDARG; 490 491 return E_FAIL; 492 } 493 494 static HRESULT WINAPI domattr_get_xml( 495 IXMLDOMAttribute *iface, 496 BSTR* p) 497 { 498 domattr *This = impl_from_IXMLDOMAttribute( iface ); 499 500 TRACE("(%p)->(%p)\n", This, p); 501 502 return node_get_xml(&This->node, FALSE, p); 503 } 504 505 static HRESULT WINAPI domattr_transformNode( 506 IXMLDOMAttribute *iface, 507 IXMLDOMNode *node, BSTR *p) 508 { 509 domattr *This = impl_from_IXMLDOMAttribute( iface ); 510 TRACE("(%p)->(%p %p)\n", This, node, p); 511 return node_transform_node(&This->node, node, p); 512 } 513 514 static HRESULT WINAPI domattr_selectNodes( 515 IXMLDOMAttribute *iface, 516 BSTR p, IXMLDOMNodeList** outList) 517 { 518 domattr *This = impl_from_IXMLDOMAttribute( iface ); 519 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); 520 return node_select_nodes(&This->node, p, outList); 521 } 522 523 static HRESULT WINAPI domattr_selectSingleNode( 524 IXMLDOMAttribute *iface, 525 BSTR p, IXMLDOMNode** outNode) 526 { 527 domattr *This = impl_from_IXMLDOMAttribute( iface ); 528 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); 529 return node_select_singlenode(&This->node, p, outNode); 530 } 531 532 static HRESULT WINAPI domattr_get_parsed( 533 IXMLDOMAttribute *iface, 534 VARIANT_BOOL* isParsed) 535 { 536 domattr *This = impl_from_IXMLDOMAttribute( iface ); 537 FIXME("(%p)->(%p) stub!\n", This, isParsed); 538 *isParsed = VARIANT_TRUE; 539 return S_OK; 540 } 541 542 static HRESULT WINAPI domattr_get_namespaceURI( 543 IXMLDOMAttribute *iface, 544 BSTR* p) 545 { 546 domattr *This = impl_from_IXMLDOMAttribute( iface ); 547 xmlNsPtr ns = This->node.node->ns; 548 549 TRACE("(%p)->(%p)\n", This, p); 550 551 if (!p) 552 return E_INVALIDARG; 553 554 *p = NULL; 555 556 if (ns) 557 { 558 /* special case for default namespace definition */ 559 if (xmlStrEqual(This->node.node->name, xmlns)) 560 *p = bstr_from_xmlChar(xmlns); 561 else if (xmlStrEqual(ns->prefix, xmlns)) 562 *p = SysAllocStringLen(NULL, 0); 563 else if (ns->href) 564 *p = bstr_from_xmlChar(ns->href); 565 } 566 567 TRACE("uri: %s\n", debugstr_w(*p)); 568 569 return *p ? S_OK : S_FALSE; 570 } 571 572 static HRESULT WINAPI domattr_get_prefix( 573 IXMLDOMAttribute *iface, 574 BSTR* prefix) 575 { 576 domattr *This = impl_from_IXMLDOMAttribute( iface ); 577 xmlNsPtr ns = This->node.node->ns; 578 579 TRACE("(%p)->(%p)\n", This, prefix); 580 581 if (!prefix) return E_INVALIDARG; 582 583 *prefix = NULL; 584 585 if (ns) 586 { 587 /* special case for default namespace definition */ 588 if (xmlStrEqual(This->node.node->name, xmlns)) 589 *prefix = bstr_from_xmlChar(xmlns); 590 else if (ns->prefix) 591 *prefix = bstr_from_xmlChar(ns->prefix); 592 } 593 594 TRACE("prefix: %s\n", debugstr_w(*prefix)); 595 596 return *prefix ? S_OK : S_FALSE; 597 } 598 599 static HRESULT WINAPI domattr_get_baseName( 600 IXMLDOMAttribute *iface, 601 BSTR* name) 602 { 603 domattr *This = impl_from_IXMLDOMAttribute( iface ); 604 TRACE("(%p)->(%p)\n", This, name); 605 return node_get_base_name( &This->node, name ); 606 } 607 608 static HRESULT WINAPI domattr_transformNodeToObject( 609 IXMLDOMAttribute *iface, 610 IXMLDOMNode* domNode, VARIANT var1) 611 { 612 domattr *This = impl_from_IXMLDOMAttribute( iface ); 613 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); 614 return E_NOTIMPL; 615 } 616 617 static HRESULT WINAPI domattr_get_name( 618 IXMLDOMAttribute *iface, 619 BSTR *p) 620 { 621 domattr *This = impl_from_IXMLDOMAttribute( iface ); 622 623 TRACE("(%p)->(%p)\n", This, p); 624 625 return node_get_nodeName(&This->node, p); 626 } 627 628 static HRESULT WINAPI domattr_get_value( 629 IXMLDOMAttribute *iface, 630 VARIANT *value) 631 { 632 domattr *This = impl_from_IXMLDOMAttribute( iface ); 633 634 TRACE("(%p)->(%p)\n", This, value); 635 636 return node_get_content(&This->node, value); 637 } 638 639 static HRESULT WINAPI domattr_put_value( 640 IXMLDOMAttribute *iface, 641 VARIANT value) 642 { 643 domattr *This = impl_from_IXMLDOMAttribute( iface ); 644 645 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); 646 647 return node_put_value_escaped(&This->node, &value); 648 } 649 650 static const struct IXMLDOMAttributeVtbl domattr_vtbl = 651 { 652 domattr_QueryInterface, 653 domattr_AddRef, 654 domattr_Release, 655 domattr_GetTypeInfoCount, 656 domattr_GetTypeInfo, 657 domattr_GetIDsOfNames, 658 domattr_Invoke, 659 domattr_get_nodeName, 660 domattr_get_nodeValue, 661 domattr_put_nodeValue, 662 domattr_get_nodeType, 663 domattr_get_parentNode, 664 domattr_get_childNodes, 665 domattr_get_firstChild, 666 domattr_get_lastChild, 667 domattr_get_previousSibling, 668 domattr_get_nextSibling, 669 domattr_get_attributes, 670 domattr_insertBefore, 671 domattr_replaceChild, 672 domattr_removeChild, 673 domattr_appendChild, 674 domattr_hasChildNodes, 675 domattr_get_ownerDocument, 676 domattr_cloneNode, 677 domattr_get_nodeTypeString, 678 domattr_get_text, 679 domattr_put_text, 680 domattr_get_specified, 681 domattr_get_definition, 682 domattr_get_nodeTypedValue, 683 domattr_put_nodeTypedValue, 684 domattr_get_dataType, 685 domattr_put_dataType, 686 domattr_get_xml, 687 domattr_transformNode, 688 domattr_selectNodes, 689 domattr_selectSingleNode, 690 domattr_get_parsed, 691 domattr_get_namespaceURI, 692 domattr_get_prefix, 693 domattr_get_baseName, 694 domattr_transformNodeToObject, 695 domattr_get_name, 696 domattr_get_value, 697 domattr_put_value 698 }; 699 700 static const tid_t domattr_iface_tids[] = { 701 IXMLDOMAttribute_tid, 702 0 703 }; 704 705 static dispex_static_data_t domattr_dispex = { 706 NULL, 707 IXMLDOMAttribute_tid, 708 NULL, 709 domattr_iface_tids 710 }; 711 712 IUnknown* create_attribute( xmlNodePtr attribute ) 713 { 714 domattr *This; 715 716 This = heap_alloc( sizeof *This ); 717 if ( !This ) 718 return NULL; 719 720 This->IXMLDOMAttribute_iface.lpVtbl = &domattr_vtbl; 721 This->ref = 1; 722 723 init_xmlnode(&This->node, attribute, (IXMLDOMNode*)&This->IXMLDOMAttribute_iface, &domattr_dispex); 724 725 return (IUnknown*)&This->IXMLDOMAttribute_iface; 726 } 727 728 #endif 729