XMLDOMDocument.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:35k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: XMLDOMDocument.cpp,v 1.9 2001/10/24 19:11:39 tng Exp $
  58.  */
  59. #include "stdafx.h"
  60. #include <parsers/DOMParser.hpp>
  61. #include <sax/SAXParseException.hpp>
  62. #include <framework/MemBufInputSource.hpp>
  63. #include "xml4com.h"
  64. #include "XMLDOMDocument.h"
  65. #include "XMLDOMUtil.h"
  66. #include "XMLDOMNodeList.h"
  67. #include "XMLDOMNamedNodeMap.h"
  68. #include "XMLDOMDocumentType.h"
  69. #include "XMLDOMImplementation.h"
  70. #include "XMLDOMElement.h"
  71. #include "XMLDOMDocumentFragment.h"
  72. #include "XMLDOMText.h"
  73. #include "XMLDOMComment.h"
  74. #include "XMLDOMCDATASection.h"
  75. #include "XMLDOMProcessingInstruction.h"
  76. #include "XMLDOMAttribute.h"
  77. #include "XMLDOMEntityReference.h"
  78. #include "BindStatusCallback.h"
  79. #include <dom/DocumentImpl.hpp>
  80. // I need to make sure the file is registered with long filenames
  81. HRESULT WINAPI CXMLDOMDocument::UpdateRegistry(BOOL bRegister)
  82. {
  83. USES_CONVERSION;
  84. TCHAR file[MAX_PATH];
  85. if (::GetModuleFileName(_Module.m_hInst, file, MAX_PATH)) {
  86. WIN32_FIND_DATA d;
  87. memset(&d,0,sizeof(WIN32_FIND_DATA));
  88. HANDLE h = FindFirstFile(file,&d);
  89. if (h != INVALID_HANDLE_VALUE) {
  90. TCHAR  *name = _tcsrchr(file,_T('\'));
  91. TCHAR newFile[MAX_PATH] = _T("");
  92. _tcsncpy(newFile,file,name-file);
  93. _tcscat(newFile,_T("\"));
  94. _tcscat(newFile,d.cFileName);
  95. FindClose(h);
  96. _ATL_REGMAP_ENTRY regmap[2] = {{NULL,NULL},{NULL,NULL}};
  97. regmap[0].szKey  = OLESTR("XMLMODULE");
  98. regmap[0].szData = T2OLE(newFile);
  99. return _Module.UpdateRegistryFromResource((UINT) IDR_XMLDOCUMENT, bRegister,regmap);
  100. }
  101. }
  102. return E_FAIL;
  103. }
  104. CXMLDOMDocument::CXMLDOMDocument()
  105. :m_Document ()
  106. ,m_bValidate (false)
  107. ,m_lReadyState (0)
  108. ,m_url (_T(""))
  109. ,m_pParseError (NULL)
  110. ,m_bAsync (false)
  111. ,m_bAbort (false)
  112. ,m_hParseThread (NULL)
  113. ,m_pOnReadyStateChange (NULL)
  114. ,m_pOnDataAvailable (NULL)
  115. ,m_pOnTransformNode (NULL)
  116. ,m_FileName (_T(""))
  117. ,m_xml (_T(""))
  118. ,m_bParseError (false)
  119. ,m_bThreadValidate (false)
  120. ,m_bPreserveWhiteSpace      (false)
  121. {
  122. }
  123. HRESULT CXMLDOMDocument::FinalConstruct()
  124. {
  125. // create monitor window
  126. RECT rc;
  127.     memset(&rc,0,sizeof(RECT));
  128. if (NULL == Create(NULL, rc, _T("XML Parse Monitor Window"), 0))
  129. return E_FAIL;
  130. HRESULT hr = CXMLDOMParseErrorObj::CreateInstance(&m_pParseError);
  131. if (S_OK != hr)
  132. return hr;
  133. m_pParseError->AddRef();
  134. m_pIXMLDOMDocument = this;
  135. m_Document = DOM_Document::createDocument();
  136. return hr;
  137. }
  138. void CXMLDOMDocument::FinalRelease()
  139. {
  140. if (NULL != m_hParseThread) {
  141. m_bAbort = true;
  142. ::WaitForSingleObject(m_hParseThread, INFINITE);
  143. ::CloseHandle(m_hParseThread);
  144. m_hParseThread = NULL;
  145. }
  146. if (m_pParseError != NULL) {
  147. m_pParseError->Release();
  148. m_pParseError = NULL;
  149. }
  150. if (m_pOnReadyStateChange != NULL) {
  151. m_pOnReadyStateChange->Release();
  152. m_pOnReadyStateChange = NULL;
  153. }
  154. if (m_pOnDataAvailable != NULL) {
  155. m_pOnDataAvailable->Release();
  156. m_pOnDataAvailable = NULL;
  157. }
  158. if (m_pOnTransformNode != NULL) {
  159. m_pOnTransformNode->Release();
  160. m_pOnTransformNode = NULL;
  161. }
  162. DestroyWindow();
  163. }
  164. void CXMLDOMDocument::warning(const SAXParseException& exception)
  165. {
  166. // ignore warnings
  167. }
  168. void CXMLDOMDocument::error(const SAXParseException& exception)
  169. {
  170. m_pParseError->SetData(1,
  171.    exception.getSystemId(),
  172.    exception.getMessage(),
  173.    _T(""),
  174.    exception.getLineNumber(),
  175.    exception.getColumnNumber(),
  176.    0);
  177. m_bParseError = true;
  178. }
  179. void CXMLDOMDocument::fatalError(const SAXParseException& exception)
  180. {
  181. m_pParseError->SetData(1,
  182.    exception.getSystemId(),
  183.    exception.getMessage(),
  184.    _T(""),
  185.    exception.getLineNumber(),
  186.    exception.getColumnNumber(),
  187.    0);
  188. m_bParseError = true;
  189. }
  190. LRESULT CXMLDOMDocument::OnReadyStateChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  191. {
  192. ATLTRACE(_T("CXMLDOMDocument::OnReadyStateChangen"));
  193. bHandled = TRUE;
  194. m_lReadyState = wParam;
  195. Fire_onreadystatechange();
  196. if (NULL != m_pOnReadyStateChange) {
  197. CComVariant varResult;
  198. DISPPARAMS disp = { NULL, NULL, 0, 0 };
  199. m_pOnReadyStateChange->Invoke(DISPID_VALUE, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
  200. }
  201. if (m_lReadyState != 4)
  202. return 1L;
  203. m_Document = m_TmpDocument;
  204. m_TmpDocument = 0;
  205. m_url = m_FileName;
  206. if (!m_bParseError) {
  207. Fire_ondataavailable();
  208. if (NULL != m_pOnDataAvailable) {
  209. CComVariant varResult;
  210. DISPPARAMS disp = { NULL, NULL, 0, 0 };
  211. m_pOnDataAvailable->Invoke(DISPID_VALUE, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
  212. }
  213. }
  214. return 1L;
  215. }
  216. STDMETHODIMP CXMLDOMDocument::InterfaceSupportsErrorInfo(REFIID riid)
  217. {
  218. if (IsEqualGUID(IID_IXMLDOMDocument,riid))
  219. return S_OK;
  220. return S_FALSE;
  221. }
  222. STDMETHODIMP CXMLDOMDocument::get_doctype(IXMLDOMDocumentType  **pVal)
  223. {
  224. ATLTRACE(_T("CXMLDOMDocument::get_doctypen"));
  225. if (NULL == pVal)
  226. return E_POINTER;
  227. *pVal = NULL;
  228. DOM_DocumentType doctype = m_Document.getDoctype();
  229. //
  230. //   if the document had no doctype then return a null object
  231. //
  232. if(doctype.isNull())
  233. return S_OK;
  234. CXMLDOMDocumentTypeObj *pObj = NULL;
  235. HRESULT hr = CXMLDOMDocumentTypeObj::CreateInstance(&pObj);
  236. if (S_OK != hr)
  237. return hr;
  238. pObj->AddRef();
  239. pObj->SetOwnerDoc(this);
  240. try
  241. {
  242. pObj->documentType = doctype;
  243. }
  244. catch(...)
  245. {
  246. pObj->Release();
  247. return E_FAIL;
  248. }
  249. hr = pObj->QueryInterface(IID_IXMLDOMDocumentType, reinterpret_cast<LPVOID*> (pVal));
  250. if (S_OK != hr)
  251. *pVal = NULL;
  252. pObj->Release();
  253. return hr;
  254. }
  255. STDMETHODIMP CXMLDOMDocument::get_implementation(IXMLDOMImplementation  **pVal)
  256. {
  257. ATLTRACE(_T("CXMLDOMDocument::get_implementationn"));
  258. if (NULL == pVal)
  259. return E_POINTER;
  260. *pVal = NULL;
  261. CXMLDOMImplementationObj *pObj = NULL;
  262. HRESULT hr = CXMLDOMImplementationObj::CreateInstance(&pObj);
  263. if (S_OK != hr)
  264. return hr;
  265. pObj->AddRef();
  266. hr = pObj->QueryInterface(IID_IXMLDOMImplementation, reinterpret_cast<LPVOID*> (pVal));
  267. if (S_OK != hr)
  268. *pVal = NULL;
  269. pObj->Release();
  270. return hr;
  271. }
  272. STDMETHODIMP CXMLDOMDocument::get_documentElement(IXMLDOMElement  * *pVal)
  273. {
  274. ATLTRACE(_T("CXMLDOMDocument::get_documentElementn"));
  275. if (NULL == pVal)
  276. return E_POINTER;
  277. *pVal = NULL;
  278. CXMLDOMElementObj *pObj = NULL;
  279. HRESULT hr = CXMLDOMElementObj::CreateInstance(&pObj);
  280. if (S_OK != hr)
  281. return S_OK;
  282. pObj->AddRef();
  283. pObj->SetOwnerDoc(this);
  284. try
  285. {
  286. pObj->element = m_Document.getDocumentElement();
  287. }
  288. catch(DOM_DOMException& ex)
  289. {
  290. pObj->Release();
  291. return MakeHRESULT(ex);
  292. }
  293. catch(...)
  294. {
  295. pObj->Release();
  296. return S_OK;
  297. }
  298. hr = pObj->QueryInterface(IID_IXMLDOMElement, reinterpret_cast<LPVOID*> (pVal));
  299. if (S_OK != hr)
  300. *pVal = NULL;
  301. pObj->Release();
  302. return S_OK;
  303. }
  304. STDMETHODIMP CXMLDOMDocument::putref_documentElement(IXMLDOMElement  *newVal)
  305. {
  306. ATLTRACE(_T("CXMLDOMDocument::putref_documentElementn"));
  307. DOM_Element elem;
  308. try
  309. {
  310. elem = m_Document.getDocumentElement();
  311. if (NULL == newVal && !elem.isNull()) {
  312. m_Document.removeChild(elem);
  313. return S_OK;
  314. }
  315. }
  316. catch(DOM_DOMException& ex)
  317. {
  318. return MakeHRESULT(ex);
  319. }
  320. catch(...)
  321. {
  322. return E_FAIL;
  323. }
  324. CComQIPtr<IIBMXMLDOMNodeIdentity,&IID_IIBMXMLDOMNodeIdentity> pNewVal(newVal);
  325. if (!pNewVal)
  326. return E_NOINTERFACE;
  327. long id = 0;
  328. HRESULT hr = pNewVal->get_NodeId(&id);
  329. if (S_OK != hr)
  330. return hr;
  331. DOM_Node *pNewValNode = reinterpret_cast<DOM_Node*> (id);
  332. if (NULL == pNewValNode)
  333. return E_INVALIDARG;
  334. try
  335. {
  336. if(elem.isNull())
  337. m_Document.appendChild(*pNewValNode);
  338. else
  339. m_Document.replaceChild(*pNewValNode, elem);
  340. }
  341. catch(DOM_DOMException& ex)
  342. {
  343. return MakeHRESULT(ex);
  344. }
  345. catch(...)
  346. {
  347. return E_FAIL;
  348. }
  349. return S_OK;
  350. }
  351. STDMETHODIMP CXMLDOMDocument::createElement(BSTR tagName, IXMLDOMElement  **pVal)
  352. {
  353. ATLTRACE(_T("CXMLDOMDocument::createElementn"));
  354. if (NULL == pVal)
  355. return E_POINTER;
  356. *pVal = NULL;
  357. CXMLDOMElementObj *pObj = NULL;
  358. HRESULT hr = CXMLDOMElementObj::CreateInstance(&pObj);
  359. if (S_OK != hr)
  360. return hr;
  361. pObj->AddRef();
  362. pObj->SetOwnerDoc(this);
  363. try
  364. {
  365. pObj->element = m_Document.createElement(tagName);
  366. }
  367. catch(DOM_DOMException& ex)
  368. {
  369. pObj->Release();
  370. return MakeHRESULT(ex);
  371. }
  372. catch(...)
  373. {
  374. pObj->Release();
  375. return E_FAIL;
  376. }
  377. hr = pObj->QueryInterface(IID_IXMLDOMElement, reinterpret_cast<LPVOID*> (pVal));
  378. if (S_OK != hr)
  379. *pVal = NULL;
  380. pObj->Release();
  381. return hr;
  382. }
  383. STDMETHODIMP CXMLDOMDocument::createDocumentFragment(IXMLDOMDocumentFragment  **docFrag)
  384. {
  385. ATLTRACE(_T("CXMLDOMDocument::createDocumentFragmentn"));
  386. if (NULL == docFrag)
  387. return E_POINTER;
  388. *docFrag = NULL;
  389. CXMLDOMDocumentFragmentObj *pObj = NULL;
  390. HRESULT hr = CXMLDOMDocumentFragmentObj::CreateInstance(&pObj);
  391. if (S_OK != hr)
  392. return hr;
  393. pObj->AddRef();
  394. pObj->SetOwnerDoc(this);
  395. try
  396. {
  397. pObj->documentFragment = m_Document.createDocumentFragment();
  398. }
  399. catch(DOM_DOMException& ex)
  400. {
  401. pObj->Release();
  402. return MakeHRESULT(ex);
  403. }
  404. catch(...)
  405. {
  406. pObj->Release();
  407. return E_FAIL;
  408. }
  409. hr = pObj->QueryInterface(IID_IXMLDOMDocumentFragment, reinterpret_cast<LPVOID*> (docFrag));
  410. if (S_OK != hr)
  411. *docFrag = NULL;
  412. pObj->Release();
  413. return hr;
  414. }
  415. STDMETHODIMP CXMLDOMDocument::createTextNode(BSTR data, IXMLDOMText  **pVal)
  416. {
  417. ATLTRACE(_T("CXMLDOMDocument::createTextNoden"));
  418. if (NULL == pVal)
  419. return E_POINTER;
  420. *pVal = NULL;
  421. CXMLDOMTextObj *pObj = NULL;
  422. HRESULT hr = CXMLDOMTextObj::CreateInstance(&pObj);
  423. if (S_OK != hr)
  424. return hr;
  425. pObj->AddRef();
  426. pObj->SetOwnerDoc(this);
  427. try
  428. {
  429. pObj->text = m_Document.createTextNode(data);
  430. }
  431. catch(DOM_DOMException& ex)
  432. {
  433. pObj->Release();
  434. return MakeHRESULT(ex);
  435. }
  436. catch(...)
  437. {
  438. pObj->Release();
  439. return E_FAIL;
  440. }
  441. hr = pObj->QueryInterface(IID_IXMLDOMText, reinterpret_cast<LPVOID*> (pVal));
  442. if (S_OK != hr)
  443. *pVal = NULL;
  444. pObj->Release();
  445. return hr;
  446. }
  447. STDMETHODIMP CXMLDOMDocument::createComment(BSTR data, IXMLDOMComment  **comment)
  448. {
  449. ATLTRACE(_T("CXMLDOMDocument::createCommentn"));
  450. if (NULL == comment)
  451. return E_POINTER;
  452. *comment = NULL;
  453. CXMLDOMCommentObj *pObj = NULL;
  454. HRESULT hr = CXMLDOMCommentObj::CreateInstance(&pObj);
  455. if (S_OK != hr)
  456. return hr;
  457. pObj->AddRef();
  458. pObj->SetOwnerDoc(this);
  459. try
  460. {
  461. pObj->comment = m_Document.createComment(data);
  462. }
  463. catch(DOM_DOMException& ex)
  464. {
  465. pObj->Release();
  466. return MakeHRESULT(ex);
  467. }
  468. catch(...)
  469. {
  470. pObj->Release();
  471. return E_FAIL;
  472. }
  473. hr = pObj->QueryInterface(IID_IXMLDOMComment, reinterpret_cast<LPVOID*> (comment));
  474. if (S_OK != hr)
  475. *comment = NULL;
  476. pObj->Release();
  477. return hr;
  478. }
  479. STDMETHODIMP CXMLDOMDocument::createCDATASection(BSTR data, IXMLDOMCDATASection  **cdata)
  480. {
  481. ATLTRACE(_T("CXMLDOMDocument::createCDATASectionn"));
  482. if (NULL == cdata)
  483. return E_POINTER;
  484. *cdata = NULL;
  485. CXMLDOMCDATASectionObj *pObj = NULL;
  486. HRESULT hr = CXMLDOMCDATASectionObj::CreateInstance(&pObj);
  487. if (S_OK != hr)
  488. return hr;
  489. pObj->AddRef();
  490. pObj->SetOwnerDoc(this);
  491. try
  492. {
  493. pObj->cdataSection = m_Document.createCDATASection(data);
  494. }
  495. catch(DOM_DOMException& ex)
  496. {
  497. pObj->Release();
  498. return MakeHRESULT(ex);
  499. }
  500. catch(...)
  501. {
  502. pObj->Release();
  503. return E_FAIL;
  504. }
  505. hr = pObj->QueryInterface(IID_IXMLDOMCDATASection, reinterpret_cast<LPVOID*> (cdata));
  506. if (S_OK != hr)
  507. *cdata = NULL;
  508. pObj->Release();
  509. return hr;
  510. }
  511. STDMETHODIMP CXMLDOMDocument::createProcessingInstruction(BSTR target, BSTR data, IXMLDOMProcessingInstruction  **pVal)
  512. {
  513. ATLTRACE(_T("CXMLDOMDocument::createProcessingInstructionn"));
  514. if (NULL == pVal)
  515. return E_POINTER;
  516. *pVal = NULL;
  517. CXMLDOMProcessingInstructionObj *pObj = NULL;
  518. HRESULT hr = CXMLDOMProcessingInstructionObj::CreateInstance(&pObj);
  519. if (S_OK != hr)
  520. return hr;
  521. pObj->AddRef();
  522. pObj->SetOwnerDoc(this);
  523. try
  524. {
  525. pObj->processingInstruction = m_Document.createProcessingInstruction(target, data);
  526. }
  527. catch(DOM_DOMException& ex)
  528. {
  529. pObj->Release();
  530. return MakeHRESULT(ex);
  531. }
  532. catch(...)
  533. {
  534. pObj->Release();
  535. return E_FAIL;
  536. }
  537. hr = pObj->QueryInterface(IID_IXMLDOMProcessingInstruction, reinterpret_cast<LPVOID*> (pVal));
  538. if (S_OK != hr)
  539. *pVal = NULL;
  540. pObj->Release();
  541. return hr;
  542. }
  543. STDMETHODIMP CXMLDOMDocument::createAttribute(BSTR name, IXMLDOMAttribute  **attr)
  544. {
  545. ATLTRACE(_T("CXMLDOMDocument::createAttributen"));
  546. if (NULL == attr)
  547. return E_POINTER;
  548. *attr = NULL;
  549. CXMLDOMAttributeObj *pObj = NULL;
  550. HRESULT hr = CXMLDOMAttributeObj::CreateInstance(&pObj);
  551. if (S_OK != hr)
  552. return hr;
  553. pObj->AddRef();
  554. pObj->SetOwnerDoc(this);
  555. try
  556. {
  557. pObj->attr = m_Document.createAttribute(name);
  558. }
  559. catch(DOM_DOMException& ex)
  560. {
  561. pObj->Release();
  562. return MakeHRESULT(ex);
  563. }
  564. catch(...)
  565. {
  566. pObj->Release();
  567. return E_FAIL;
  568. }
  569. hr = pObj->QueryInterface(IID_IXMLDOMAttribute, reinterpret_cast<LPVOID*> (attr));
  570. if (S_OK != hr)
  571. *attr = NULL;
  572. pObj->Release();
  573. return hr;
  574. }
  575. STDMETHODIMP CXMLDOMDocument::createEntityReference(BSTR name, IXMLDOMEntityReference  **entityRef)
  576. {
  577. ATLTRACE(_T("CXMLDOMDocument::createEntityReferencen"));
  578. if (NULL == entityRef)
  579. return E_POINTER;
  580. *entityRef = NULL;
  581. CXMLDOMEntityReferenceObj *pObj = NULL;
  582. HRESULT hr = CXMLDOMEntityReferenceObj::CreateInstance(&pObj);
  583. if (S_OK != hr)
  584. return hr;
  585. pObj->AddRef();
  586. pObj->SetOwnerDoc(this);
  587. try
  588. {
  589. pObj->entityReference = m_Document.createEntityReference(name);
  590. }
  591. catch(DOM_DOMException& ex)
  592. {
  593. pObj->Release();
  594. return MakeHRESULT(ex);
  595. }
  596. catch(...)
  597. {
  598. pObj->Release();
  599. return E_FAIL;
  600. }
  601. hr = pObj->QueryInterface(IID_IXMLDOMEntityReference, reinterpret_cast<LPVOID*> (entityRef));
  602. if (S_OK != hr)
  603. *entityRef = NULL;
  604. pObj->Release();
  605. return hr;
  606. }
  607. STDMETHODIMP CXMLDOMDocument::getElementsByTagName(BSTR tagName, IXMLDOMNodeList  **pVal)
  608. {
  609. ATLTRACE(_T("CXMLDOMDocument::getElementsByTagNamen"));
  610. if (NULL == pVal)
  611. return E_POINTER;
  612. *pVal = NULL;
  613. CXMLDOMNodeListObj *pObj = NULL;
  614. HRESULT hr = CXMLDOMNodeListObj::CreateInstance(&pObj);
  615. if (S_OK != hr)
  616. return hr;
  617. pObj->AddRef();
  618. pObj->SetOwnerDoc(m_pIXMLDOMDocument);
  619. try
  620. {
  621. pObj->m_container = m_Document.getElementsByTagName(tagName);
  622. }
  623. catch(DOM_DOMException& ex)
  624. {
  625. pObj->Release();
  626. return MakeHRESULT(ex);
  627. }
  628. catch(...)
  629. {
  630. pObj->Release();
  631. return E_FAIL;
  632. }
  633. hr = pObj->QueryInterface(IID_IXMLDOMNodeList, reinterpret_cast<LPVOID*> (pVal));
  634. if (S_OK != hr)
  635. *pVal = NULL;
  636. pObj->Release();
  637. return hr;
  638. }
  639. STDMETHODIMP CXMLDOMDocument::createNode(VARIANT TYPE, BSTR name, BSTR namespaceURI, IXMLDOMNode  **pVal)
  640. {
  641. ATLTRACE(_T("CXMLDOMDocument::createNoden"));
  642. HRESULT hr = S_OK;
  643. if (NULL == pVal)
  644. return E_POINTER;
  645. *pVal = NULL;
  646. VARIANT type;
  647. ::VariantInit(&type);
  648. if (V_VT(&TYPE) != VT_I4 && V_VT(&TYPE) != VT_BSTR)
  649. hr = ::VariantChangeType(&type,&TYPE,0,VT_I4); 
  650. else
  651. hr = ::VariantCopy(&type,&TYPE);
  652. if (S_OK != hr)
  653. return hr;
  654. DOMNodeType nodeType = NODE_INVALID;
  655. if (VT_I4 == V_VT(&type))
  656. nodeType = static_cast<DOMNodeType> (V_I4(&type));
  657. else {
  658. OLECHAR* str = V_BSTR(&type);
  659. for (int i = 0; i < g_DomNodeNameSize; ++i) {
  660. if (0 == _wcsicmp(str,g_DomNodeName[i])) {
  661. nodeType = static_cast<DOMNodeType> (i);
  662. break;
  663. }
  664. }
  665. }
  666. ::VariantClear(&type);
  667. if (NODE_INVALID == nodeType ||
  668. NODE_DOCUMENT == nodeType ||
  669. NODE_DOCUMENT_TYPE == nodeType ||
  670. NODE_ENTITY == nodeType ||
  671. NODE_NOTATION == nodeType)
  672. return E_FAIL;
  673. try
  674. {
  675. switch(nodeType) {
  676. case NODE_ELEMENT:
  677. {
  678. DOM_Element node;
  679. if (SysStringLen(namespaceURI) > 0)
  680. node = m_Document.createElementNS(namespaceURI,name);
  681. else
  682. node = m_Document.createElement(name);
  683. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  684. break;
  685. }
  686. case NODE_ATTRIBUTE:
  687. {
  688. DOM_Attr node;
  689. if (SysStringLen(namespaceURI) > 0)
  690. node = m_Document.createAttributeNS(namespaceURI,name);
  691. else
  692. node = m_Document.createAttribute(name);
  693. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  694. break;
  695. }
  696. case NODE_TEXT:
  697. {
  698. DOM_Text node = m_Document.createTextNode(OLESTR(""));
  699. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  700. break;
  701. }
  702. case NODE_CDATA_SECTION:
  703. {
  704. DOM_CDATASection node = m_Document.createCDATASection(OLESTR(""));
  705. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  706. break;
  707. }
  708. case NODE_ENTITY_REFERENCE:
  709. {
  710. DOM_EntityReference node = m_Document.createEntityReference(name);
  711. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  712. break;
  713. }
  714. case NODE_PROCESSING_INSTRUCTION:
  715. {
  716. DOM_ProcessingInstruction node = m_Document.createProcessingInstruction(name,OLESTR(""));
  717. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  718. break;
  719. }
  720. case NODE_COMMENT:
  721. {
  722. DOM_Comment node = m_Document.createComment(OLESTR(""));
  723. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  724. break;
  725. }
  726. case NODE_DOCUMENT_FRAGMENT:
  727. {
  728. DOM_DocumentFragment node = m_Document.createDocumentFragment();
  729. hr = wrapNode(m_pIXMLDOMDocument,node,IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  730. break;
  731. }
  732. default:
  733. hr = E_FAIL;
  734. break;
  735. }
  736. }
  737. catch(DOM_DOMException& ex)
  738. {
  739. hr = MakeHRESULT(ex);
  740. }
  741. catch (...)
  742. {
  743. hr = E_FAIL;
  744. }
  745. return hr;
  746. }
  747. STDMETHODIMP CXMLDOMDocument::nodeFromID(BSTR idString, IXMLDOMNode  **pVal)
  748. {
  749. ATLTRACE(_T("CXMLDOMDocument::nodeFromIDn"));
  750. if (NULL == pVal)
  751. return E_POINTER;
  752. *pVal = NULL;
  753. HRESULT hr = S_OK;
  754. try
  755. {
  756. hr = wrapNode(m_pIXMLDOMDocument, m_Document.getElementById(idString),IID_IXMLDOMNode,reinterpret_cast<LPVOID *> (pVal));
  757. }
  758. catch(DOM_DOMException& ex)
  759. {
  760. return MakeHRESULT(ex);
  761. }
  762. catch(...)
  763. {
  764. return E_FAIL;
  765. }
  766. return hr;
  767. }
  768. STDMETHODIMP CXMLDOMDocument::load(VARIANT xmlSource, VARIANT_BOOL  *isSuccessful)
  769. {
  770. ATLTRACE(_T("CXMLDOMDocument::loadn"));
  771. if (NULL == isSuccessful)
  772. return E_POINTER;
  773. *isSuccessful = VARIANT_FALSE;
  774. if (V_VT(&xmlSource) != VT_BSTR &&
  775. V_VT(&xmlSource) != VT_DISPATCH &&
  776. V_VT(&xmlSource) != (VT_ARRAY | VT_VARIANT) &&
  777. V_VT(&xmlSource) != (VT_ARRAY | VT_UI1) &&
  778. V_VT(&xmlSource) != VT_UNKNOWN)
  779. return E_INVALIDARG;
  780. // do not start another thread if there is another active
  781. if (NULL != m_hParseThread) {
  782. DWORD exitCode = 0;
  783. BOOL rc = ::GetExitCodeThread(m_hParseThread, &exitCode);
  784. if (!rc || STILL_ACTIVE == exitCode)
  785. return S_OK;
  786. ::CloseHandle(m_hParseThread);
  787. m_hParseThread = NULL;
  788. }
  789. HRESULT hr = S_OK;
  790. m_bAbort = false;
  791. m_FileName = _T("");
  792. m_xml = _T("");
  793. m_TmpDocument = 0;
  794. m_bThreadValidate = m_bValidate;
  795. if (V_VT(&xmlSource) == VT_BSTR) {
  796. m_FileName = V_BSTR(&xmlSource);
  797. if (0 == m_FileName.length())
  798. return E_INVALIDARG;
  799. // see if the file is relative path
  800. if (!PathIsURL(m_FileName) && PathIsRelative(m_FileName)) {
  801. // try appending baseurl if exists
  802. _bstr_t baseURL;
  803. if (S_OK == GetBaseURL(baseURL)) {
  804. // change any backslashes to slashes
  805. LPTSTR loc = _tcschr(m_FileName,_T('\'));
  806. while (loc != NULL) {
  807. *loc = _T('/');
  808. loc = _tcschr(m_FileName,_T('\'));
  809. }
  810. m_FileName = baseURL + _T("/") + m_FileName;
  811. }
  812. }
  813. }
  814. else
  815. if (V_VT(&xmlSource) == VT_UNKNOWN) {
  816. CComQIPtr<IStream,&IID_IStream> pS(V_UNKNOWN(&xmlSource));
  817. if (!pS)
  818. return E_INVALIDARG;
  819. CComBSTR b;
  820. hr = b.ReadFromStream(pS);
  821. if (S_OK != hr)
  822. return hr;
  823. m_xml = b;
  824. if (0 == m_xml.length())
  825. return E_INVALIDARG;
  826. }
  827. else
  828. if (V_VT(&xmlSource) == VT_DISPATCH) {
  829. CComQIPtr<IXMLDOMDocument,&IID_IXMLDOMDocument> pDoc(V_DISPATCH(&xmlSource));
  830. if (!pDoc)
  831. return E_INVALIDARG;
  832. BSTR b = NULL;
  833. hr = pDoc->get_xml(&b);
  834. if (S_OK != hr)
  835. return hr;
  836. m_xml = b;
  837. ::SysFreeString(b);
  838. if (0 == m_xml.length())
  839. return E_INVALIDARG;
  840. }
  841. else
  842. if (V_VT(&xmlSource) == (VT_ARRAY | VT_VARIANT)) {
  843. SAFEARRAY *pArray = reinterpret_cast<SAFEARRAY *> (xmlSource.byref);
  844. if (NULL == pArray)
  845. return E_INVALIDARG;
  846. long lLBoundVar = 0;
  847. long lUBoundVar = 0;
  848. UINT dims = ::SafeArrayGetDim(pArray);
  849. if (dims == 0)
  850. return E_INVALIDARG;
  851. hr = ::SafeArrayGetLBound(pArray, dims, &lLBoundVar);
  852. if (S_OK != hr)
  853. return hr;
  854. hr = ::SafeArrayGetUBound(pArray, dims, &lUBoundVar);
  855. if (S_OK != hr)
  856. return hr;
  857. if (lUBoundVar >= lLBoundVar) {
  858. VARIANT *pIndex = NULL;
  859. hr = ::SafeArrayAccessData(pArray, reinterpret_cast<void **> (&pIndex));
  860. if (S_OK != hr)
  861. return hr;
  862. int length = lUBoundVar-lLBoundVar+2;
  863. BYTE *body = new BYTE[length];
  864. for (long i = 0; i <= lUBoundVar-lLBoundVar; ++i) {
  865. VARIANT var = pIndex[i];
  866. if (V_VT(&var) != VT_UI1) {
  867. hr = E_INVALIDARG;
  868. break;
  869. }
  870. body[i] = V_UI1(&var);
  871. }
  872. body[length-1] = 0;
  873. ::SafeArrayUnaccessData(pArray);
  874. if (S_OK != hr) {
  875. delete [] body;
  876. return hr;
  877. }
  878. m_xml = reinterpret_cast<char*> (body);
  879. delete [] body;
  880. if (0 == m_xml.length())
  881. return E_INVALIDARG;
  882. }
  883. }
  884. else
  885. if (V_VT(&xmlSource) == (VT_ARRAY | VT_UI1)) {
  886. SAFEARRAY *pArray = reinterpret_cast<SAFEARRAY *> (xmlSource.byref);
  887. if (NULL == pArray)
  888. return E_INVALIDARG;
  889. long lLBoundVar = 0;
  890. long lUBoundVar = 0;
  891. UINT dims = ::SafeArrayGetDim(pArray);
  892. if (dims == 0)
  893. return E_INVALIDARG;
  894. hr = ::SafeArrayGetLBound(pArray, dims, &lLBoundVar);
  895. if (S_OK != hr)
  896. return hr;
  897. hr = ::SafeArrayGetUBound(pArray, dims, &lUBoundVar);
  898. if (S_OK != hr)
  899. return hr;
  900. if (lUBoundVar >= lLBoundVar) {
  901. BYTE *pIndex = NULL;
  902. hr = ::SafeArrayAccessData(pArray, reinterpret_cast<void **> (&pIndex));
  903. if (S_OK != hr)
  904. return hr;
  905. int length = lUBoundVar-lLBoundVar+2;
  906. BYTE *body = new BYTE[length];
  907. for (long i = 0; i <= lUBoundVar-lLBoundVar; ++i)
  908. body[i] = pIndex[i];
  909. body[length-1] = 0;
  910. ::SafeArrayUnaccessData(pArray);
  911. m_xml = reinterpret_cast<char*> (body);
  912. delete [] body;
  913. if (0 == m_xml.length())
  914. return E_INVALIDARG;
  915. }
  916. }
  917. UINT nthreadID = 0;
  918. m_hParseThread = reinterpret_cast<HANDLE> (_beginthreadex(NULL,
  919.  0,
  920.      CXMLDOMDocument::ParseThread,
  921.  (void *) this,
  922.  0,
  923.  &nthreadID));
  924. if (NULL == m_hParseThread)
  925. return S_OK;
  926. if (m_bAsync) {
  927. *isSuccessful = VARIANT_TRUE;
  928. return S_OK;
  929. }
  930. bool bWait = true;
  931. while (bWait) {
  932. DWORD dwEvt = MsgWaitForMultipleObjects(1,&m_hParseThread,FALSE,INFINITE,QS_ALLINPUT);
  933. switch(dwEvt) {
  934. case WAIT_OBJECT_0:
  935. bWait = false;
  936. break;
  937. case WAIT_OBJECT_0 + 1:
  938. {
  939. MSG msg;
  940. while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
  941. if (WM_CLOSE == msg.message || WM_QUIT == msg.message) {
  942.  bWait = false;
  943.  m_bAbort = true;
  944.  break;
  945. }
  946. else {
  947. PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
  948. TranslateMessage(&msg);
  949. DispatchMessage(&msg);
  950. }
  951. }
  952. break;
  953. }
  954. default:
  955. m_bAbort = true;
  956. bWait = false;
  957. break;
  958. }
  959. }
  960. if (m_bAbort)
  961. return S_OK;
  962. if (m_bParseError)
  963. return hr;
  964. m_Document = m_TmpDocument;
  965. m_TmpDocument = 0;
  966. m_url = m_FileName;
  967. *isSuccessful = VARIANT_TRUE;
  968. return hr;
  969. }
  970. HRESULT CXMLDOMDocument::GetBaseURL(_bstr_t &baseURL)
  971. {
  972. baseURL = _T("");
  973. CComPtr<IServiceProvider> pSP;
  974. HRESULT hr = GetSite(IID_IServiceProvider, reinterpret_cast<LPVOID *> (&pSP));
  975.     if (S_OK != hr)
  976. return hr;
  977. CComPtr<IWebBrowser2> pWB;
  978.     hr = pSP->QueryService(SID_SWebBrowserApp,IID_IWebBrowser2,
  979.                                  reinterpret_cast<LPVOID *> (&pWB));
  980. if (S_OK != hr)
  981. return hr;
  982. BSTR b = NULL;
  983. hr = pWB->get_LocationURL(&b);
  984. if (S_OK != hr)
  985. return hr;
  986. TCHAR url[MAX_PATH] = _T("");
  987. lstrcat(url,_bstr_t(b));
  988. // look for last slash and remove the filename after it
  989. LPTSTR loc = _tcsrchr(url, _T('/'));
  990. if (loc != NULL) {
  991. TCHAR str[MAX_PATH] = _T("");
  992. _tcsncpy(str, url, loc - url);
  993. lstrcpy(url,str);
  994. }
  995. baseURL = url;
  996. return hr;
  997. }
  998. STDMETHODIMP CXMLDOMDocument::get_readyState(long  *pVal)
  999. {
  1000. ATLTRACE(_T("CXMLDOMDocument::get_readyStaten"));
  1001. if (NULL == pVal)
  1002. return E_POINTER;
  1003. *pVal = m_lReadyState;
  1004. return S_OK;
  1005. }
  1006. STDMETHODIMP CXMLDOMDocument::get_parseError(IXMLDOMParseError  **pVal)
  1007. {
  1008. ATLTRACE(_T("CXMLDOMDocument::get_parseErrorn"));
  1009. if (NULL == pVal)
  1010. return E_POINTER;
  1011. return m_pParseError->QueryInterface(IID_IXMLDOMParseError, reinterpret_cast<LPVOID*> (pVal));
  1012. }
  1013. STDMETHODIMP CXMLDOMDocument::get_url(BSTR  *pVal)
  1014. {
  1015. ATLTRACE(_T("CXMLDOMDocument::get_urln"));
  1016. if (NULL == pVal)
  1017. return E_POINTER;
  1018. *pVal = m_url.copy();
  1019. return S_OK;
  1020. }
  1021. STDMETHODIMP CXMLDOMDocument::get_async(VARIANT_BOOL  *pVal)
  1022. {
  1023. ATLTRACE(_T("CXMLDOMDocument::get_asyncn"));
  1024. if (NULL == pVal)
  1025. return E_POINTER;
  1026. *pVal = m_bAsync ? VARIANT_TRUE : VARIANT_FALSE;
  1027. return S_OK;
  1028. }
  1029. STDMETHODIMP CXMLDOMDocument::put_async(VARIANT_BOOL newVal)
  1030. {
  1031. ATLTRACE(_T("CXMLDOMDocument::put_asyncn"));
  1032. m_bAsync = (VARIANT_TRUE == newVal) ? true : false;
  1033. return S_OK;
  1034. }
  1035. STDMETHODIMP CXMLDOMDocument::abort(void)
  1036. {
  1037. ATLTRACE(_T("CXMLDOMDocument::abortn"));
  1038. m_bAbort = true;
  1039. return S_OK;
  1040. }
  1041. STDMETHODIMP CXMLDOMDocument::loadXML(BSTR bstrXML, VARIANT_BOOL  *isSuccessful)
  1042. {
  1043. ATLTRACE(_T("CXMLDOMDocument::loadXMLn"));
  1044. if (NULL == isSuccessful)
  1045. return E_POINTER;
  1046. *isSuccessful = VARIANT_FALSE;
  1047. // do not start another thread if there is another active
  1048. if (NULL != m_hParseThread) {
  1049. DWORD exitCode = 0;
  1050. BOOL rc = ::GetExitCodeThread(m_hParseThread, &exitCode);
  1051. if (!rc || STILL_ACTIVE == exitCode)
  1052. return S_OK;
  1053. ::CloseHandle(m_hParseThread);
  1054. m_hParseThread = NULL;
  1055. }
  1056. HRESULT hr = S_OK;
  1057. m_bAbort = false;
  1058. m_FileName = _T("");
  1059. m_TmpDocument = 0;
  1060. m_bThreadValidate = m_bValidate;
  1061. m_xml = bstrXML;
  1062. if (0 == m_xml.length())
  1063. return E_INVALIDARG;
  1064. UINT nthreadID = 0;
  1065. m_hParseThread = reinterpret_cast<HANDLE> (_beginthreadex(NULL,
  1066.  0,
  1067.      CXMLDOMDocument::ParseThread,
  1068.  (void *) this,
  1069.  0,
  1070.  &nthreadID));
  1071. if (NULL == m_hParseThread)
  1072. return S_OK;
  1073. if (m_bAsync) {
  1074. *isSuccessful = VARIANT_TRUE;
  1075. return S_OK;
  1076. }
  1077. bool bWait = true;
  1078. while (bWait) {
  1079. DWORD dwEvt = MsgWaitForMultipleObjects(1,&m_hParseThread,FALSE,INFINITE,QS_ALLINPUT);
  1080. switch(dwEvt) {
  1081. case WAIT_OBJECT_0:
  1082. bWait = false;
  1083. break;
  1084. case WAIT_OBJECT_0 + 1:
  1085. {
  1086. MSG msg;
  1087. while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
  1088. if (WM_CLOSE == msg.message || WM_QUIT == msg.message) {
  1089.  bWait = false;
  1090.  m_bAbort = true;
  1091.  break;
  1092. }
  1093. else {
  1094. PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
  1095. TranslateMessage(&msg);
  1096. DispatchMessage(&msg);
  1097. }
  1098. }
  1099. break;
  1100. }
  1101. default:
  1102. m_bAbort = true;
  1103. bWait = false;
  1104. break;
  1105. }
  1106. }
  1107. if (m_bAbort)
  1108. return S_OK;
  1109. if (m_bParseError)
  1110. return hr;
  1111. m_Document = m_TmpDocument;
  1112. m_TmpDocument = 0;
  1113. m_url = m_FileName;
  1114. *isSuccessful = VARIANT_TRUE;
  1115. return hr;
  1116. }
  1117. UINT APIENTRY CXMLDOMDocument::ParseThread(void *pParm)
  1118. {
  1119. ATLTRACE(_T("CXMLDOMDocument::ParseThreadn"));
  1120. CXMLDOMDocument *pThis = reinterpret_cast<CXMLDOMDocument *> (pParm);
  1121. if (NULL == pThis)
  1122. return 0;
  1123. if (!pThis->m_bAbort && pThis->m_FileName.length() > 0) {
  1124. CBindStatCallbackObj *pCallbackObj = NULL;
  1125. HRESULT hr = CBindStatCallbackObj::CreateInstance(&pCallbackObj);
  1126. if (S_OK != hr)
  1127. pCallbackObj = NULL;
  1128. if (pCallbackObj != NULL) {
  1129. pCallbackObj->AddRef();
  1130. pCallbackObj->m_pDoc = pThis;
  1131. }
  1132. TCHAR name[MAX_PATH] = _T("");
  1133. if (pThis->m_bAsync)
  1134. pThis->PostMessage(MSG_READY_STATE_CHANGE,1);
  1135. hr = URLDownloadToCacheFile(NULL,pThis->m_FileName,name,URLOSTRM_GETNEWESTVERSION,0,pCallbackObj);
  1136. if (pCallbackObj != NULL)
  1137. pCallbackObj->Release();
  1138. if (E_ABORT == hr)
  1139. pThis->m_bAbort = true;
  1140. else {
  1141. if (S_OK != hr) {
  1142. _bstr_t error = _T("Failed to download ") + pThis->m_FileName + _T(": ");
  1143. _com_error comError(hr);
  1144. error += comError.ErrorMessage();
  1145. pThis->m_pParseError->SetData(1,pThis->m_FileName,error,_T(""),0,0,0);
  1146. pThis->m_bParseError = true;
  1147. }
  1148. }
  1149. if (S_OK == hr) {
  1150. pThis->m_FileName = name;
  1151. if (pThis->m_bAsync)
  1152. pThis->PostMessage(MSG_READY_STATE_CHANGE,2);
  1153. }
  1154. }
  1155. DOMParser parser;
  1156. //
  1157. //   If set to true then an node supporting IXMLDOMProcessingInstruction
  1158. //     is added for the XML declaration.
  1159. //
  1160. //   Setting to true in a custom DLL will better mimic
  1161. //      MSXML.DLL but at a cost of conformance errors
  1162. //      using David Brownell's suite
  1163. parser.setToCreateXMLDeclTypeNode(false);
  1164. parser.setIncludeIgnorableWhitespace(pThis->m_bPreserveWhiteSpace);
  1165. if (!pThis->m_bParseError && !pThis->m_bAbort) {
  1166. parser.setDoValidation(pThis->m_bThreadValidate);
  1167. //
  1168. //   this brings the COM component into better mimicry to MSXML
  1169. //      by not throwing a validation error when there is no DOCTYPE
  1170. //
  1171. parser.setValidationScheme(pThis->m_bThreadValidate ? DOMParser::Val_Auto : DOMParser::Val_Never);
  1172. }
  1173. if (!pThis->m_bParseError && !pThis->m_bAbort)
  1174. parser.setErrorHandler(pThis);
  1175. if (!pThis->m_bParseError && !pThis->m_bAbort)
  1176. pThis->m_pParseError->Reset();
  1177. if (!pThis->m_bParseError && !pThis->m_bAbort)
  1178. pThis->m_bParseError = false;
  1179. try
  1180. {
  1181. if (!pThis->m_bParseError && !pThis->m_bAbort) {
  1182. if (pThis->m_FileName.length() > 0)
  1183. parser.parse(static_cast<LPCTSTR> (pThis->m_FileName));
  1184. else {
  1185. XMLByte *pXMLByte =  reinterpret_cast<XMLByte*> (static_cast<XMLCh*>(pThis->m_xml));
  1186. MemBufInputSource memBufIS(pXMLByte,pThis->m_xml.length()*sizeof(XMLCh),OLESTR("IBMXMLParser"),false);
  1187. memBufIS.setEncoding(OLESTR("UTF-16LE"));
  1188. if (!pThis->m_bParseError && !pThis->m_bAbort)
  1189. parser.parse(memBufIS);
  1190. }
  1191. }
  1192. }
  1193. catch(...)
  1194. {
  1195. pThis->m_bParseError = true;
  1196. return 0;
  1197. }
  1198. if (!pThis->m_bParseError && !pThis->m_bAbort)
  1199. pThis->m_TmpDocument = parser.getDocument();
  1200. if (!pThis->m_bParseError && !pThis->m_bAbort && pThis->m_bAsync)
  1201. pThis->PostMessage(MSG_READY_STATE_CHANGE,4);
  1202.   
  1203. return 0;
  1204. }
  1205. STDMETHODIMP CXMLDOMDocument::save(VARIANT location)
  1206. {
  1207. ATLTRACE(_T("CXMLDOMDocument::saven"));
  1208. if (V_VT(&location) != VT_BSTR)
  1209. return E_INVALIDARG;
  1210. _bstr_t file(V_BSTR(&location));
  1211. if (0 == file.length())
  1212. return E_INVALIDARG;
  1213. _bstr_t text;
  1214. try {
  1215. DOM_NodeList childs = m_Document.getChildNodes();
  1216. int length = childs.getLength();
  1217. for (int i=0; i < length; ++i) {
  1218. DOM_Node child = childs.item(i);
  1219. GetXML(child,text);
  1220. }
  1221. }
  1222. catch(DOM_DOMException& ex)
  1223. {
  1224. return MakeHRESULT(ex);
  1225. }
  1226. catch(...)
  1227. {
  1228. return E_FAIL;
  1229. }
  1230. FILE* fp;
  1231. if ((fp = _tfopen(file, "wt")) == NULL) {
  1232. return E_FAIL;
  1233. }
  1234. _ftprintf(fp, text);
  1235. fclose(fp);
  1236. return S_OK;
  1237. }
  1238. STDMETHODIMP CXMLDOMDocument::get_validateOnParse(VARIANT_BOOL  *pVal)
  1239. {
  1240. ATLTRACE(_T("CXMLDOMDocument::get_validateOnParsen"));
  1241. if (NULL == pVal)
  1242. return E_POINTER;
  1243. *pVal = (m_bValidate) ? VARIANT_TRUE : VARIANT_FALSE;
  1244. return S_OK;
  1245. }
  1246. STDMETHODIMP CXMLDOMDocument::put_validateOnParse(VARIANT_BOOL newVal)
  1247. {
  1248. ATLTRACE(_T("CXMLDOMDocument::put_validateOnParsen"));
  1249. m_bValidate = (VARIANT_TRUE == newVal) ? true : false;
  1250. return S_OK;
  1251. }
  1252. STDMETHODIMP CXMLDOMDocument::get_resolveExternals(VARIANT_BOOL  *pVal)
  1253. {
  1254. ATLTRACE(_T("CXMLDOMDocument::get_resolveExternalsn"));
  1255. if (NULL == pVal)
  1256. return E_POINTER;
  1257. return E_NOTIMPL;
  1258. }
  1259. STDMETHODIMP CXMLDOMDocument::put_resolveExternals(VARIANT_BOOL newVal)
  1260. {
  1261. ATLTRACE(_T("CXMLDOMDocument::put_resolveExternalsn"));
  1262. return E_NOTIMPL;
  1263. }
  1264. STDMETHODIMP CXMLDOMDocument::get_preserveWhiteSpace(VARIANT_BOOL  *pVal)
  1265. {
  1266. ATLTRACE(_T("CXMLDOMDocument::get_preserveWhiteSpacen"));
  1267. if (NULL == pVal)
  1268. return E_POINTER;
  1269. *pVal = (m_bPreserveWhiteSpace) ? VARIANT_TRUE : VARIANT_FALSE;
  1270. return S_OK;
  1271. }
  1272. STDMETHODIMP CXMLDOMDocument::put_preserveWhiteSpace(VARIANT_BOOL newVal)
  1273. {
  1274. ATLTRACE(_T("CXMLDOMDocument::put_preserveWhiteSpacen"));
  1275. m_bPreserveWhiteSpace = (VARIANT_TRUE == newVal) ? true : false;
  1276. return S_OK;
  1277. }
  1278. STDMETHODIMP CXMLDOMDocument::put_onreadystatechange(VARIANT newVal)
  1279. {
  1280. ATLTRACE(_T("CXMLDOMDocument::put_onreadystatechangen"));
  1281. if (VT_DISPATCH != V_VT(&newVal) &&
  1282. VT_NULL != V_VT(&newVal))
  1283. return E_INVALIDARG;
  1284. LPDISPATCH pDisp = NULL;
  1285. if (VT_DISPATCH == V_VT(&newVal))
  1286. pDisp = V_DISPATCH(&newVal);
  1287. if (m_pOnReadyStateChange != NULL) {
  1288. m_pOnReadyStateChange->Release();
  1289. m_pOnReadyStateChange = NULL;
  1290. }
  1291. m_pOnReadyStateChange = pDisp;
  1292. if (m_pOnReadyStateChange != NULL)
  1293. m_pOnReadyStateChange->AddRef();
  1294. return S_OK;
  1295. }
  1296. STDMETHODIMP CXMLDOMDocument::put_ondataavailable(VARIANT newVal)
  1297. {
  1298. ATLTRACE(_T("CXMLDOMDocument::put_ondataavailablen"));
  1299. if (VT_DISPATCH != V_VT(&newVal) &&
  1300. VT_NULL != V_VT(&newVal))
  1301. return E_INVALIDARG;
  1302. LPDISPATCH pDisp = NULL;
  1303. if (VT_DISPATCH == V_VT(&newVal))
  1304. pDisp = V_DISPATCH(&newVal);
  1305. if (m_pOnDataAvailable != NULL) {
  1306. m_pOnDataAvailable->Release();
  1307. m_pOnDataAvailable = NULL;
  1308. }
  1309. m_pOnDataAvailable = pDisp;
  1310. if (m_pOnDataAvailable != NULL)
  1311. m_pOnDataAvailable->AddRef();
  1312. return S_OK;
  1313. }
  1314. STDMETHODIMP CXMLDOMDocument::put_ontransformnode(VARIANT newVal)
  1315. {
  1316. ATLTRACE(_T("CXMLDOMDocument::put_ontransformnoden"));
  1317. if (VT_DISPATCH != V_VT(&newVal) &&
  1318. VT_NULL != V_VT(&newVal))
  1319. return E_INVALIDARG;
  1320. LPDISPATCH pDisp = NULL;
  1321. if (VT_DISPATCH == V_VT(&newVal))
  1322. pDisp = V_DISPATCH(&newVal);
  1323. if (m_pOnTransformNode != NULL) {
  1324. m_pOnTransformNode->Release();
  1325. m_pOnTransformNode = NULL;
  1326. }
  1327. m_pOnTransformNode = pDisp;
  1328. if (m_pOnTransformNode != NULL)
  1329. m_pOnTransformNode->AddRef();
  1330. return S_OK;
  1331. }