void CXmlItem::Copy(const CXmlItem& xi, BOOL bCopySiblings) { Reset(); // copy own name and value m_sName = xi.GetName(); m_sValue = xi.GetValue(); m_nType = xi.GetType(); // copy siblings if (bCopySiblings) { const CXmlItem* pXISibling = xi.GetSibling(); if (pXISibling) m_pSibling = new CXmlItem(*pXISibling, m_pParent); } // copy children POSITION pos = xi.GetFirstItemPos(); while (pos) { const CXmlItem* pXIChild = xi.GetNextItem(pos); ASSERT (pXIChild); AddItem(*pXIChild, TRUE); } }
CXmlItem* CXmlItem::GetItem(const CString& sItemName, int nIndex) { CXmlItem* pXI = GetItem(sItemName); while (pXI && nIndex--) pXI = pXI->GetSibling(); return pXI; }
BOOL CXmlItem::RemoveItem(CXmlItem* pXI) { if (!pXI) return FALSE; // lookup by name first const CString& sName = pXI->GetName(); CXmlItem* pXIMatch = GetItem(sName); if (!pXIMatch) return FALSE; // now search the sibling chain looking for exact match CXmlItem* pXIPrevSibling = NULL; while (pXIMatch != pXI) { pXIPrevSibling = pXIMatch; pXIMatch = pXIMatch->GetSibling(); } if (!pXIMatch) // no match return FALSE; // else ASSERT (pXIMatch == pXI); CXmlItem* pNextSibling = pXI->GetSibling(); if (!pXIPrevSibling) // head of the chain { POSITION pos = m_lstItems.Find(pXI); if (!pNextSibling) m_lstItems.RemoveAt(pos); else m_lstItems.SetAt(pos, pNextSibling); } else // somewhere else in the chain { pXIPrevSibling->m_pSibling = pNextSibling; // can be NULL } // clear item's sibling pXI->m_pSibling = NULL; // and parent pXI->m_pParent = NULL; return TRUE; }
BOOL CXmlFileEx::Decrypt(LPCTSTR szPassword) { if (!IsEncrypted()) return TRUE; // nothing to do // we don't try to decrypt if no encryption capabilities if (!CanEncrypt()) { m_nFileError = XFL_NOENCRYPTIONDLL; return FALSE; } // use existing password if required if (!szPassword) szPassword = m_sPassword; CXmlItem* pXI = GetEncryptedBlock(); if (pXI && !pXI->GetSibling()) { // else keep getting password till success or user cancels while (TRUE) { CString sPassword(szPassword); if (sPassword.IsEmpty()) { CString sExplanation(s_sPasswordExplanation); if (sExplanation.Find(_T("%s")) != -1) sExplanation.Format(s_sPasswordExplanation, GetFileName()); if (!CPasswordDialog::RetrievePassword(FALSE, sPassword, sExplanation)) { // RB - Set m_nFileError to avoid "The selected task list could not be opened..." message when cancelling m_nFileError = XFL_CANCELLED; return FALSE; } } CString sFile; if (Decrypt(pXI->GetValue(), sFile, sPassword)) { m_sPassword = sPassword; sFile.TrimLeft(); sFile.TrimRight(); sFile = _T("<ROOT>") + sFile + _T("</ROOT>"); // delete the cdata item m_xiRoot.DeleteItem(pXI); try { CXmlDocumentWrapper doc; // reparse decrypted xml if (doc.LoadXML(sFile)) { CXmlNodeWrapper node(doc.AsNode()); return ParseItem(m_xiRoot, &node); } } catch (...) { m_nFileError = XFL_BADMSXML; } return FALSE; } // RB - Added code to format the error message before calling AfxMessage else { CEnString sMessage(s_sDecryptFailed, GetFileName()); if (IDNO == AfxMessageBox(sMessage, MB_YESNO)) { m_nFileError = XFL_CANCELLED; return FALSE; } // else user will try again } } } // else m_nFileError = XFL_UNKNOWNENCRYPTION; return FALSE; }
void CXmlItem::SortItems(const CString& sItemName, const CString& sKeyName, XI_SORTKEY nKey, BOOL bAscending) { if (!sItemName || !sKeyName) return; // 1. sort immediate children first CXmlItem* pXIItem = GetItem(sItemName); if (!pXIItem) return; // make sure item has key value if (!pXIItem->GetItem(sKeyName)) return; // make sure at least one sibling exists BOOL bContinue = (pXIItem->GetSibling() != NULL); while (bContinue) { CXmlItem* pXIPrev = NULL; CXmlItem* pXISibling = NULL; // get this again because we have to anyway // for subsequent loops pXIItem = GetItem(sItemName); POSITION pos = m_lstItems.Find(pXIItem); // reset continue flag so that if there are no // switches then the sorting is done bContinue = FALSE; pXISibling = pXIItem->GetSibling(); while (pXISibling) { int nCompare = CompareItems(pXIItem, pXISibling, sKeyName, nKey); if (!bAscending) nCompare = -nCompare; if (nCompare > 0) { // switch items if (pXIPrev) pXIPrev->m_pSibling = pXISibling; else // we're at the head of the chain { m_lstItems.SetAt(pos, pXISibling); // m_mapItems[sItemName] = pXISibling; } pXIItem->m_pSibling = pXISibling->m_pSibling; pXISibling->m_pSibling = pXIItem; pXIPrev = pXISibling; bContinue = TRUE; // loop once more } else { pXIPrev = pXIItem; pXIItem = pXISibling; } pXISibling = pXIItem->GetSibling(); // next } } // 2. sort children's children pXIItem = GetItem(sItemName); while (pXIItem) { pXIItem->SortItems(sItemName, sKeyName, nKey, bAscending); pXIItem = pXIItem->GetSibling(); } }