//helper function to append a sub node child to a documentfragment with given name and value: HRESULT AddSubNodeToDocumentFragment( IXMLDOMDocument* pDOM, const wchar_t* wszSubNodeName, const wchar_t* wszSubNodeValue, IXMLDOMDocumentFragment* pdf // Release is completed outside ) { BSTR bstr = NULL; IXMLDOMElement* peSub = NULL; HRESULT hr = S_OK; do { bstr = SysAllocString(wszSubNodeName); HR_SUCCESSCALL( pDOM->createElement(bstr, &peSub), hr ); SAFE_BSTR_RELEASE(bstr); bstr=SysAllocString(wszSubNodeValue); HR_SUCCESSCALL( peSub->put_text(bstr), hr ); HR_SUCCESSCALL( AppendChildToParent(peSub, pdf), hr ); }while(0); //release the com object SAFE_COM_RELEASE(peSub); //release the bstr SAFE_BSTR_RELEASE(bstr); return hr; }
int DicomImageSet::parseFolder(QString folderName) { QStringList fileList = getAllFiles(folderName); HRESULT hr = CoInitialize(NULL); if (!SUCCEEDED(hr)) { return NULL; } hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMElement *pRoot = NULL; BSTR bstrXML = NULL; VARIANT varFileName; VariantInit(&varFileName); QProgressDialog progress (QString("Parsing all files in %1").arg(folderName), QString("Cancel"), 0, fileList.count()); CHK_HR(CreateAndInitDOM(&pXMLDom)); // Create a processing instruction element. CHK_HR(CreateAndAddPINode(pXMLDom, L"xml", L"version='1.0'")); // Create the root element. CHK_HR(CreateElement(pXMLDom, L"root", &pRoot)); // Create an attribute for the <root> element, with name "created" and value "using dom". CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"path", folderName.toStdWString().c_str(), pRoot)); // Add NEWLINE for identation before </root>. CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pRoot)); // add <root> to document CHK_HR(AppendChildToParent(pRoot, pXMLDom)); progress.show(); for (int i=0; i<fileList.count(); ++i) { insertFileItem(pXMLDom, pRoot, folderName, fileList[i]); progress.setValue(i); } CHK_HR(VariantFromString(QDir(folderName).filePath(DATASET_FILE_NAME).toStdWString().c_str(), varFileName)); CHK_HR(pXMLDom->save(varFileName)); CleanUp: SAFE_RELEASE(pRoot); SysFreeString(bstrXML); VariantClear(&varFileName); CoUninitialize(); if (FAILED(hr)) { SAFE_RELEASE(pXMLDom); return 0; } return 1; }
int DicomImageSet::insertDTIFileItem(const QString &datasetFolderName, const QString &queryString, const QString &dtiFileName) { HRESULT hr = CoInitialize(NULL); if (!SUCCEEDED(hr)) { return 0; } QString datasetFileName = datasetFolderName+DATASET_FILE_NAME; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMElement *pNode = NULL, *pParent = NULL; BSTR bstrQuery = NULL; VARIANT varFileName; VARIANT_BOOL varStatus; QString queryDTIFile; CHK_HR(CreateAndInitDOM(&pXMLDom)); CHK_HR(VariantFromString(datasetFileName.toStdWString().c_str(), varFileName)); CHK_HR(pXMLDom->load(varFileName, &varStatus)); /*queryDTIFile = queryString+QString("/DTI[@file_name = '%1']").arg(dtiFileName); bstrQuery = SysAllocString(queryString.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pNode)); SysFreeString(bstrQuery); if (pNode) { return 1; }*/ bstrQuery = SysAllocString(queryString.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pParent)); SysFreeString(bstrQuery); if (pParent) { CHK_HR(CreateElement(pXMLDom, L"DTI", &pNode)); CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"file_name", dtiFileName.toStdWString().c_str(), pNode)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pParent)); CHK_HR(AppendChildToParent(pNode, pParent)); CHK_HR(pXMLDom->save(varFileName)); return 1; } CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pNode); return 0; }
//put xml file element function HRESULT PutXMLFileHead(IXMLDOMDocument* pDOM, IXMLDOMElement** ppRoot) { IXMLDOMProcessingInstruction *pi = NULL; HRESULT hr = S_OK; do { //create a processing instruction element. _bstr_t header = L"xml"; _bstr_t content = L"version='1.0' encoding='utf-8'"; HR_SUCCESSCALL( pDOM->createProcessingInstruction(header,content, &pi), hr ); HR_SUCCESSCALL( AppendChildToParent(pi, pDOM), hr ); //create the root element. _bstr_t root = L"VideoStrcuture"; HR_SUCCESSCALL( pDOM->createElement(root, ppRoot), hr ); HR_SUCCESSCALL( AppendChildToParent(*ppRoot, pDOM), hr ); }while(0); //release the com object SAFE_COM_RELEASE(pi); return hr; }
// Helper function to create and add a comment to a document node. HRESULT XMLHelper::CreateAndAddCommentNode(IXMLDOMDocument *pDom, PCWSTR wszComment) { HRESULT hr = S_OK; IXMLDOMComment *pComment = NULL; BSTR bstrComment = SysAllocString(wszComment); CHK_ALLOC(bstrComment); CHK_HR(pDom->createComment(bstrComment, &pComment)); CHK_HR(AppendChildToParent(pComment, pDom)); CleanUp: SAFE_RELEASE(pComment); SysFreeString(bstrComment); return hr; }
// Helper function to create and append a CDATA node to a parent node. HRESULT XMLHelper::CreateAndAddCDATANode(IXMLDOMDocument *pDom, PCWSTR wszCDATA, IXMLDOMNode *pParent) { HRESULT hr = S_OK; IXMLDOMCDATASection *pCDATA = NULL; BSTR bstrCDATA = SysAllocString(wszCDATA); CHK_ALLOC(bstrCDATA); CHK_HR(pDom->createCDATASection(bstrCDATA, &pCDATA)); CHK_HR(AppendChildToParent(pCDATA, pParent)); CleanUp: SAFE_RELEASE(pCDATA); SysFreeString(bstrCDATA); return hr; }
// Helper function to create and append a text node to a parent node. HRESULT XMLHelper::CreateAndAddTextNode(IXMLDOMDocument *pDom, PCWSTR wszText, IXMLDOMNode *pParent) { HRESULT hr = S_OK; IXMLDOMText *pText = NULL; BSTR bstrText = SysAllocString(wszText); CHK_ALLOC(bstrText); CHK_HR(pDom->createTextNode(bstrText, &pText)); CHK_HR(AppendChildToParent(pText, pParent)); CleanUp: SAFE_RELEASE(pText); SysFreeString(bstrText); return hr; }
// Helper function to create and add a processing instruction to a document node. HRESULT XMLHelper::CreateAndAddPINode(IXMLDOMDocument *pDom, PCWSTR wszTarget, PCWSTR wszData) { HRESULT hr = S_OK; IXMLDOMProcessingInstruction *pPI = NULL; BSTR bstrTarget = SysAllocString(wszTarget); BSTR bstrData = SysAllocString(wszData); CHK_ALLOC(bstrTarget && bstrData); CHK_HR(pDom->createProcessingInstruction(bstrTarget, bstrData, &pPI)); CHK_HR(AppendChildToParent(pPI, pDom)); CleanUp: SAFE_RELEASE(pPI); SysFreeString(bstrTarget); SysFreeString(bstrData); return hr; }
// Helper function to create and append an element node to a parent node, and pass the newly created // element node to caller if it wants. HRESULT XMLHelper::CreateAndAddElementNode(IXMLDOMDocument *pDom, PCWSTR wszName, PCWSTR wszNewline, IXMLDOMNode *pParent, IXMLDOMElement **ppElement) { HRESULT hr = S_OK; IXMLDOMElement* pElement = NULL; CHK_HR(CreateElement(pDom, wszName, &pElement)); // Add NEWLINE+TAB for identation before this element. CHK_HR(CreateAndAddTextNode(pDom, wszNewline, pParent)); // Append this element to parent. CHK_HR(AppendChildToParent(pElement, pParent)); CleanUp: if (ppElement) *ppElement = pElement; // Caller is repsonsible to release this element. else SAFE_RELEASE(pElement); // Caller is not interested on this element, so release it. return hr; }
IXMLDOMNode * DicomImageSet::findParentNode(IXMLDOMDocument *pXMLDom, IXMLDOMNode * pRoot, const char * patientsName, const char * patientsId, int acquisitionDate, const char * protocol, int acquisitionNumber) { if (!pXMLDom) { return NULL; } HRESULT hr = S_OK; IXMLDOMElement *pPatient = NULL, *pDate = NULL, *pProtocol = NULL, *pCollection = NULL; BSTR bstrQuery = NULL; QString strQuery; bool nodeExist = false; //look for the patient node strQuery = QString("root/Patient[@patients_name = '%1' and @patient_id = '%2']").arg(patientsName).arg(patientsId); bstrQuery = SysAllocString(strQuery.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pPatient)); SysFreeString(bstrQuery); nodeExist = pPatient; if (!nodeExist) { //create the patient node CHK_HR(CreateElement(pXMLDom, L"Patient", &pPatient)); CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"patients_name", QString(patientsName).toStdWString().c_str(), pPatient)); CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"patient_id", QString(patientsId).toStdWString().c_str(), pPatient)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pRoot)); CHK_HR(AppendChildToParent(pPatient, pRoot)); } if (nodeExist) { //look for the date node strQuery = QString("Date[@acquisition_date = '%1']").arg(acquisitionDate); bstrQuery = SysAllocString(strQuery.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pPatient->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pDate)); SysFreeString(bstrQuery); nodeExist = pDate; } if (!nodeExist) { CHK_HR(CreateElement(pXMLDom, L"Date", &pDate)); CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"acquisition_date", QString::number(acquisitionDate).toStdWString().c_str(), pDate)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pPatient)); CHK_HR(AppendChildToParent(pDate, pPatient)); } if (nodeExist) { //look for the protocol node strQuery = QString("Protocol[@protocol_name = '%1']").arg(protocol); bstrQuery = SysAllocString(strQuery.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pDate->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pProtocol)); SysFreeString(bstrQuery); nodeExist = pProtocol; } if (!nodeExist) { CHK_HR(CreateElement(pXMLDom, L"Protocol", &pProtocol)); CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"protocol_name", QString(protocol).toStdWString().c_str(), pProtocol)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pDate)); CHK_HR(AppendChildToParent(pProtocol, pDate)); } if (nodeExist) { //look for the collection node strQuery = QString("Collection[@acquisition_number = '%1']").arg(acquisitionNumber); bstrQuery = SysAllocString(strQuery.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pProtocol->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pCollection)); SysFreeString(bstrQuery); nodeExist = pCollection; } if (!nodeExist) { CHK_HR(CreateElement(pXMLDom, L"Collection", &pCollection)); CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"acquisition_number", QString::number(acquisitionNumber).toStdWString().c_str(), pCollection)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pProtocol)); CHK_HR(AppendChildToParent(pCollection, pProtocol)); } CleanUp: SAFE_RELEASE(pPatient); SAFE_RELEASE(pDate); SAFE_RELEASE(pProtocol); if(SUCCEEDED(hr)) { return pCollection; } SAFE_RELEASE(pCollection); return NULL; }
//add Id array to a document fragment node HRESULT AddIdsNode( IXMLDOMDocument* pDOM, BSTR indentBstr, const wchar_t* wszIdsNodeName, const wchar_t* wszIdsNodeAttribute, const wchar_t* wszIdNode, const std::vector<int>& ids, IXMLDOMDocumentFragment* pdf // Release is completed outside ) { VARIANT var; BSTR bstr = NULL; BSTR bstr_wst = SysAllocString(L"\t"); IXMLDOMElement* pe = NULL; IXMLDOMDocumentFragment* pdfSub = NULL; IXMLDOMAttribute *pa = NULL; IXMLDOMAttribute *pa1 = NULL; HRESULT hr = S_OK; do { //create a Node to hold ids. bstr = SysAllocString(wszIdsNodeName); HR_SUCCESSCALL( pDOM->createElement(bstr, &pe), hr ); SAFE_BSTR_RELEASE(bstr); //create a attribute for the <wszIdsNodeName> element, and //assign the element num as the attribute value. //get ids num string size_t idsNum = ids.size(); const int radix = 10; const size_t sizeOfstr = 30; wchar_t wszIdsNumString[sizeOfstr] = {0}; _ultow_s(static_cast<unsigned long>(idsNum), wszIdsNumString, sizeOfstr, radix); //put num string into attribute bstr = SysAllocString(wszIdsNodeAttribute); VariantInit(&var); V_BSTR(&var) = SysAllocString(wszIdsNumString); V_VT(&var) = VT_BSTR; HR_SUCCESSCALL( pDOM->createAttribute(bstr, &pa), hr ); HR_SUCCESSCALL( pa->put_value(var), hr ); HR_SUCCESSCALL( pe->setAttributeNode(pa, &pa1), hr ); //create a document fragment to hold ids sub-elements. HR_SUCCESSCALL( pDOM->createDocumentFragment(&pdfSub), hr ); //add ids to pdfSub for( size_t i=0; i < idsNum; ++i ) { int id = ids[i]; WCHAR wszIdString[sizeOfstr] = {0}; _itow_s(id, wszIdString, sizeOfstr, radix); //add white space before <id> HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pdfSub), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, bstr_wst, pdfSub), hr ); HR_SUCCESSCALL( AddSubNodeToDocumentFragment(pDOM, wszIdNode, wszIdString, pdfSub), hr ); } //test whether it is successful in "add ids to pdfSub" HR_SUCCESSCALL( hr, hr ); //add ids array to document fragment node HR_SUCCESSCALL( AppendChildToParent(pdfSub, pe), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pe), hr ); HR_SUCCESSCALL( AppendChildToParent(pe, pdf), hr ); }while(0); //release the com objects SAFE_COM_RELEASE(pa1); SAFE_COM_RELEASE(pa); SAFE_COM_RELEASE(pdfSub); SAFE_COM_RELEASE(pe); //release the bstr and variant SAFE_BSTR_RELEASE(bstr); SAFE_BSTR_RELEASE(bstr_wst); VariantClear(&var); return hr; }
//add boundary to shot or sub shot fragment node HRESULT AddBoundaryNodeToDocumentFragment( IXMLDOMDocument* pDOM, BSTR indentBstr, IXMLDOMDocumentFragment* pdf, // Release is completed outside unsigned int bgnFrameId, unsigned int endFrameId, __int64 bgnFrameTime, __int64 endFrameTime) { BSTR bstr = NULL; BSTR bstr_wst = SysAllocString(L"\t"); IXMLDOMElement* pe = NULL; IXMLDOMDocumentFragment* pdfSub = NULL; HRESULT hr = S_OK; do { //create a Node to hold boundary. bstr = SysAllocString(L"Boundary"); HR_SUCCESSCALL( pDOM->createElement(bstr, &pe), hr ); SAFE_BSTR_RELEASE(bstr); //create a document fragment to hold boundary's sub-elements. HR_SUCCESSCALL( pDOM->createDocumentFragment(&pdfSub), hr ); //add sub elements to pdfSub //add white space before <BgnFrameId> HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pdfSub), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, bstr_wst, pdfSub), hr ); const int radix = 10; const size_t sizeOfstr = 30; wchar_t wszBgnFrmIdString[sizeOfstr] = {0}; _itow_s(bgnFrameId, wszBgnFrmIdString, sizeOfstr, radix); HR_SUCCESSCALL( AddSubNodeToDocumentFragment(pDOM, L"BgnFrameId", wszBgnFrmIdString, pdfSub), hr ); //<EndFrameId> HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pdfSub), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, bstr_wst, pdfSub), hr ); wchar_t wszEndFrmIdString[sizeOfstr] = {0}; _itow_s(endFrameId, wszEndFrmIdString, sizeOfstr, radix); HR_SUCCESSCALL( AddSubNodeToDocumentFragment(pDOM, L"EndFrameId", wszEndFrmIdString, pdfSub), hr ); //<BgnFrameTime> HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pdfSub), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, bstr_wst, pdfSub), hr ); //begintime wchar_t wszBgnFrmTimeString[sizeOfstr*2] = {0}; _i64tow_s(bgnFrameTime, wszBgnFrmTimeString, sizeOfstr*2, 10); HR_SUCCESSCALL( AddSubNodeToDocumentFragment(pDOM, L"BgnFrameTime", wszBgnFrmTimeString, pdfSub), hr ); //<EndFrameId> HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pdfSub), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, bstr_wst, pdfSub), hr ); //endtime wchar_t wszEndFrmTimeString[sizeOfstr*2] = {0}; _i64tow_s(endFrameTime, wszEndFrmTimeString, sizeOfstr*2, 10); HR_SUCCESSCALL( AddSubNodeToDocumentFragment(pDOM, L"EndFrameTime", wszEndFrmTimeString, pdfSub), hr ); //add Boundary to document fragment node HR_SUCCESSCALL( AppendChildToParent(pdfSub, pe), hr ); HR_SUCCESSCALL( AddWhiteSpaceToNode(pDOM, indentBstr, pe), hr ); HR_SUCCESSCALL( AppendChildToParent(pe, pdf), hr ); }while(0); //release com object SAFE_COM_RELEASE(pdfSub); SAFE_COM_RELEASE(pe); //release bstr SAFE_BSTR_RELEASE(bstr); SAFE_BSTR_RELEASE(bstr_wst); return hr; }
void dynamDOM() { HRESULT hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMElement *pRoot = NULL; IXMLDOMElement *pNode = NULL; IXMLDOMElement *pSubNode = NULL; IXMLDOMDocumentFragment *pDF = NULL; BSTR bstrXML = NULL; VARIANT varFileName; VariantInit(&varFileName); CHK_HR(CreateAndInitDOM(&pXMLDom)); // Create a processing instruction element. CHK_HR(CreateAndAddPINode(pXMLDom, L"xml", L"version='1.0'")); // Create a comment element. CHK_HR(CreateAndAddCommentNode(pXMLDom, L"sample xml file created using XML DOM object.")); // Create the root element. CHK_HR(CreateElement(pXMLDom, L"root", &pRoot)); // Create an attribute for the <root> element, with name "created" and value "using dom". CHK_HR(CreateAndAddAttributeNode(pXMLDom, L"created", L"using dom", pRoot)); // Next, we will create and add three nodes to the <root> element. // Create a <node1> to hold text content. CHK_HR(CreateAndAddElementNode(pXMLDom, L"node1", L"\n\t", pRoot, &pNode)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"some character data", pNode)); SAFE_RELEASE(pNode); // Create a <node2> to hold a CDATA section. CHK_HR(CreateAndAddElementNode(pXMLDom, L"node2", L"\n\t", pRoot, &pNode)); CHK_HR(CreateAndAddCDATANode(pXMLDom, L"<some mark-up text>", pNode)); SAFE_RELEASE(pNode); // Create <node3> to hold a doc fragment with three sub-elements. CHK_HR(CreateAndAddElementNode(pXMLDom, L"node3", L"\n\t", pRoot, &pNode)); // Create a document fragment to hold three sub-elements. CHK_HR(pXMLDom->createDocumentFragment(&pDF)); // Create 3 subnodes. CHK_HR(CreateAndAddElementNode(pXMLDom, L"subNode1", L"\n\t\t", pDF)); CHK_HR(CreateAndAddElementNode(pXMLDom, L"subNode2", L"\n\t\t", pDF)); CHK_HR(CreateAndAddElementNode(pXMLDom, L"subNode3", L"\n\t\t", pDF)); CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n\t", pDF)); // Append pDF to <node3>. CHK_HR(AppendChildToParent(pDF, pNode)); SAFE_RELEASE(pNode); // Add NEWLINE for identation before </root>. CHK_HR(CreateAndAddTextNode(pXMLDom, L"\n", pRoot)); // add <root> to document CHK_HR(AppendChildToParent(pRoot, pXMLDom)); CHK_HR(pXMLDom->get_xml(&bstrXML)); wprintf(L"Dynamically created DOM:\n%s\n", bstrXML); CHK_HR(VariantFromString(L"dynamDOM.xml", varFileName)); CHK_HR(pXMLDom->save(varFileName)); wprintf(L"DOM saved to dynamDOM.xml\n"); CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pRoot); SAFE_RELEASE(pNode); SAFE_RELEASE(pDF); SAFE_RELEASE(pSubNode); SysFreeString(bstrXML); VariantClear(&varFileName); }