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;
}
// 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;
}
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);
}