// Helper function to create and add an attribute to a parent node. HRESULT XMLHelper::CreateAndAddAttributeNode(IXMLDOMDocument *pDom, PCWSTR wszName, PCWSTR wszValue, IXMLDOMElement *pParent) { HRESULT hr = S_OK; IXMLDOMAttribute *pAttribute = NULL; IXMLDOMAttribute *pAttributeOut = NULL; // Out param that is not used BSTR bstrName = NULL; VARIANT varValue; VariantInit(&varValue); bstrName = SysAllocString(wszName); CHK_ALLOC(bstrName); CHK_HR(VariantFromString(wszValue, varValue)); CHK_HR(pDom->createAttribute(bstrName, &pAttribute)); CHK_HR(pAttribute->put_value(varValue)); CHK_HR(pParent->setAttributeNode(pAttribute, &pAttributeOut)); CleanUp: SAFE_RELEASE(pAttribute); SAFE_RELEASE(pAttributeOut); SysFreeString(bstrName); VariantClear(&varValue); return hr; }
// Helper function to create a VT_BSTR variant from a null terminated string. HRESULT XMLHelper::VariantFromString(PCWSTR wszValue, VARIANT &Variant) { HRESULT hr = S_OK; BSTR bstr = SysAllocString(wszValue); CHK_ALLOC(bstr); V_VT(&Variant) = VT_BSTR; V_BSTR(&Variant) = bstr; CleanUp: return hr; }
// Helper that allocates the BSTR param for the caller. HRESULT XMLHelper::CreateElement(IXMLDOMDocument *pXMLDom, PCWSTR wszName, IXMLDOMElement **ppElement) { HRESULT hr = S_OK; *ppElement = NULL; BSTR bstrName = SysAllocString(wszName); CHK_ALLOC(bstrName); CHK_HR(pXMLDom->createElement(bstrName, ppElement)); CleanUp: SysFreeString(bstrName); return hr; }
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; }
// 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; }
HRESULT XMLHelper::CreateAndAddTextNodeBefore(IXMLDOMDocument *pDom, PCWSTR wszText, IXMLDOMNode *pParent, IXMLDOMNode *pPosition) { HRESULT hr = S_OK; IXMLDOMText *pText = NULL; BSTR bstrText = SysAllocString(wszText); CHK_ALLOC(bstrText); CHK_HR(pDom->createTextNode(bstrText, &pText)); CHK_HR(InsertChildToParent(pText, pPosition, pParent)); CleanUp: SAFE_RELEASE(pText); SysFreeString(bstrText); 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 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; }
QStringList DicomImageSet::getOrderedDcmFiles(const QString &datasetFileName, const QString & queryString) { HRESULT hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMNodeList *pFileNodes = NULL; VARIANT_BOOL varStatus; VARIANT varFileName; BSTR bstrQuery; QStringList fileList; CHK_HR(CreateAndInitDOM(&pXMLDom)); CHK_HR(VariantFromString(datasetFileName.toStdWString().c_str(), varFileName)); CHK_HR(pXMLDom->load(varFileName, &varStatus)); if (varStatus != VARIANT_TRUE) { CHK_HR(ReportParseError(pXMLDom, "Failed to load DOM from stocks.xml.")); } bstrQuery = SysAllocString(queryString.toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectNodes(bstrQuery, &pFileNodes)); if (pFileNodes) { long nFiles; CHK_HR(pFileNodes->get_length(&nFiles)); for (long i=0; i<nFiles; ++i) { VARIANT varValue; IXMLDOMNode * pFile = NULL; CHK_HR(pFileNodes->get_item(i, &pFile)); CHK_HR(GetAttributeFromNode(pFile, L"path", &varValue)); fileList <<QString::fromWCharArray(_bstr_t(varValue)); SAFE_RELEASE(pFile); } } CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pFileNodes); return fileList; }
HRESULT XMLHelper::SetAttribute(PCWSTR wszName, PCWSTR wszValue, IXMLDOMElement *pParent) { HRESULT hr = S_OK; BSTR bstrName = NULL; VARIANT varValue; VariantInit(&varValue); bstrName = SysAllocString(wszName); CHK_ALLOC(bstrName); CHK_HR(VariantFromString(wszValue, varValue)); CHK_HR(pParent->setAttribute(bstrName, varValue)); CleanUp: SysFreeString(bstrName); VariantClear(&varValue); return hr; }
QString DicomImageSet::getDTIFileName(const QString &datasetFolderName, const QString &queryString) { QString datasetFileName = datasetFolderName+DATASET_FILE_NAME; HRESULT hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMNode *pFileNode = NULL; VARIANT_BOOL varStatus; VARIANT varFileName; BSTR bstrQuery; QStringList fileList; CHK_HR(CreateAndInitDOM(&pXMLDom)); CHK_HR(VariantFromString(datasetFileName.toStdWString().c_str(), varFileName)); CHK_HR(pXMLDom->load(varFileName, &varStatus)); if (varStatus != VARIANT_TRUE) { CHK_HR(ReportParseError(pXMLDom, "Failed to load DOM from stocks.xml.")); } bstrQuery = SysAllocString(QString(queryString+"/DTI").toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectSingleNode(bstrQuery, &pFileNode)); if (pFileNode) { VARIANT varValue; CHK_HR(GetAttributeFromNode(pFileNode, L"file_name", &varValue)); return QString::fromWCharArray(_bstr_t(varValue)); } CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pFileNode); return QString(); }
int DicomImageSet::readDatasetFile(const QString &datasetFileName, QTreeWidget *treeWidget) { HRESULT hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMNodeList *pPatients = NULL; IXMLDOMNode *pPatient = NULL; DOMNodeType nodeType; VARIANT_BOOL varStatus; VARIANT varFileName; VARIANT varValue; BSTR bstrQuery; VariantInit(&varFileName); VariantInit(&varValue); QString queryPatient, queryDate, queryProtocol, queryCollection; CHK_HR(CreateAndInitDOM(&pXMLDom)); CHK_HR(VariantFromString(datasetFileName.toStdWString().c_str(), varFileName)); CHK_HR(pXMLDom->load(varFileName, &varStatus)); if (varStatus != VARIANT_TRUE) { CHK_HR(ReportParseError(pXMLDom, "Failed to load DOM from stocks.xml.")); } treeWidget->clear(); treeWidget->setColumnCount(1); CHK_HR(pXMLDom->getElementsByTagName(L"Patient", &pPatients)); if (pPatients) { long nPatients; CHK_HR(pPatients->get_length(&nPatients)); for (long i=0; i<nPatients; ++i) { CHK_HR(pPatients->get_item(i, &pPatient)); CHK_HR(GetAttributeFromNode(pPatient, L"patients_name", &varValue)); queryPatient = QString::fromWCharArray(_bstr_t(varValue)); QTreeWidgetItem * patientItem = new QTreeWidgetItem(treeWidget, QStringList(queryPatient)); patientItem->setExpanded(true); IXMLDOMNodeList * pDates = NULL; CHK_HR(pPatient->get_childNodes(&pDates)); long nDates; CHK_HR(pDates->get_length(&nDates)); for (long j=0; j<nDates; ++j) { IXMLDOMNode * pDate = NULL; CHK_HR(pDates->get_item(j, &pDate)); CHK_HR(pDate->get_nodeType(&nodeType)); if(nodeType!=NODE_ELEMENT) { continue; } CHK_HR(GetAttributeFromNode(pDate, L"acquisition_date", &varValue)); queryDate = QString::fromWCharArray(_bstr_t(varValue)); int intDate = queryDate.toInt(); QDate date = (QDate::fromString("1900-01-01", "yyyy-MM-dd")).addDays(intDate-693962); QTreeWidgetItem * dateItem = new QTreeWidgetItem(patientItem, QStringList(date.toString("yyyy-MM-dd"))); dateItem->setExpanded(true); IXMLDOMNodeList * pProtocols = NULL; CHK_HR(pDate->get_childNodes(&pProtocols)); long nProtocols; CHK_HR(pProtocols->get_length(&nProtocols)); for (long j=0; j<nProtocols; ++j) { IXMLDOMNode * pProtocol = NULL; CHK_HR(pProtocols->get_item(j, &pProtocol)); CHK_HR(pProtocol->get_nodeType(&nodeType)); if(nodeType!=NODE_ELEMENT) { continue; } CHK_HR(GetAttributeFromNode(pProtocol, L"protocol_name", &varValue)); queryProtocol = QString::fromWCharArray(_bstr_t(varValue)); QTreeWidgetItem * protocolItem = new QTreeWidgetItem(dateItem, QStringList(queryProtocol)); protocolItem->setExpanded(true); IXMLDOMNodeList * pCollections = NULL; CHK_HR(pProtocol->get_childNodes(&pCollections)); long nCollections; CHK_HR(pCollections->get_length(&nCollections)); for (long j=0; j<nCollections; ++j) { IXMLDOMNode * pCollection = NULL; CHK_HR(pCollections->get_item(j, &pCollection)); CHK_HR(pCollection->get_nodeType(&nodeType)); if(nodeType!=NODE_ELEMENT) { continue; } CHK_HR(GetAttributeFromNode(pCollection, L"acquisition_number", &varValue)); queryCollection = QString::fromWCharArray(_bstr_t(varValue)); QTreeWidgetItem * collectionItem = new QTreeWidgetItem(protocolItem); QString queryStr = QString("root/Patient[@patients_name = '%1']/Date[@acquisition_date = '%2']/Protocol[@protocol_name = '%3']/Collection[@acquisition_number = '%4']") .arg(queryPatient).arg(queryDate).arg(queryProtocol).arg(queryCollection); IXMLDOMElement * pDtiNode = NULL; bstrQuery = SysAllocString(QString(queryStr+"/DTI").toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pDtiNode)); SysFreeString(bstrQuery); if (pDtiNode) { collectionItem->setText(0,queryCollection+"*"); } else { collectionItem->setText(0, queryCollection); } collectionItem->setData(0, Qt::UserRole, queryStr); collectionItem->setExpanded(true); protocolItem->addChild(collectionItem); SAFE_RELEASE(pCollection); } dateItem->addChild(protocolItem); SAFE_RELEASE(pProtocol); } patientItem->addChild(dateItem); SAFE_RELEASE(pDate); } treeWidget->insertTopLevelItem(i, patientItem); SAFE_RELEASE(pPatient); } } CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pPatients); SAFE_RELEASE(pPatient); VariantClear(&varFileName); return SUCCEEDED(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; }
void queryNodes() { HRESULT hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMNodeList *pNodes = NULL; IXMLDOMNode *pNode = NULL; BSTR bstrQuery1 = NULL; BSTR bstrQuery2 = NULL; BSTR bstrNodeName = NULL; BSTR bstrNodeValue = NULL; VARIANT_BOOL varStatus; VARIANT varFileName; VariantInit(&varFileName); CHK_HR(CreateAndInitDOM(&pXMLDom)); CHK_HR(VariantFromString(L"stocks.xml", varFileName)); CHK_HR(pXMLDom->load(varFileName, &varStatus)); if (varStatus != VARIANT_TRUE) { CHK_HR(ReportParseError(pXMLDom, "Failed to load DOM from stocks.xml.")); } // Query a single node. bstrQuery1 = SysAllocString(L"//stock[1]/*"); CHK_ALLOC(bstrQuery1); CHK_HR(pXMLDom->selectSingleNode(bstrQuery1, &pNode)); if (pNode) { printf("Result from selectSingleNode:\n"); CHK_HR(pNode->get_nodeName(&bstrNodeName)); printf("Node, <%S>:\n", bstrNodeName); SysFreeString(bstrNodeName); CHK_HR(pNode->get_xml(&bstrNodeValue)); printf("\t%S\n\n", bstrNodeValue); SysFreeString(bstrNodeValue); SAFE_RELEASE(pNode); } else { CHK_HR(ReportParseError(pXMLDom, "Error while calling selectSingleNode.")); } // Query a node-set. bstrQuery2 = SysAllocString(L"//stock[1]/*"); CHK_ALLOC(bstrQuery2); CHK_HR(pXMLDom->selectNodes(bstrQuery2, &pNodes)); if(pNodes) { printf("Results from selectNodes:\n"); //get the length of node-set long length; CHK_HR(pNodes->get_length(&length)); for (long i = 0; i < length; i++) { CHK_HR(pNodes->get_item(i, &pNode)); CHK_HR(pNode->get_nodeName(&bstrNodeName)); /*if(0== wcscmp(bstrNodeValue, L"symbol")) { } */ printf("Node (%d), <%S>:\n", i, bstrNodeName); SysFreeString(bstrNodeName); CHK_HR(pNode->get_xml(&bstrNodeValue)); printf("\t%S\n", bstrNodeValue); SysFreeString(bstrNodeValue); SAFE_RELEASE(pNode); } } else { CHK_HR(ReportParseError(pXMLDom, "Error while calling selectNodes.")); } CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pNodes); SAFE_RELEASE(pNode); SysFreeString(bstrQuery1); SysFreeString(bstrQuery2); SysFreeString(bstrNodeName); SysFreeString(bstrNodeValue); VariantClear(&varFileName); }