📄 booklibrary.cpp
字号:
// 静态模型
#include "BookLibrary.h"
#include <strstream>
#include <windows.h>
#include <time.h>
#include <hahacommon.h>
namespace Library
{
using namespace std;
/// <summary>BookLibrary的缺省构造函数</summary>
/// <remarks></remarks>
BookLibrary::BookLibrary()
:classRoot(NULL),
bookRoot(NULL)
{
}
/// <summary>从一个XML文件加载图书数据</summary>
/// <param name="xmlFile">XML文件名</param>
/// <returns>成功返回0; 失败返回其他值</returns>
/// <exception cref="KXmlFileException">文件:xmlFile 无法加载</exception>
/// <exception cref="KXmlFileException">文件:xmlFile 格式错误</exception>
/// <exception cref="KXmlFileException">文件:xmlFile 无法解析</exception>
/// <remarks></remarks>
int BookLibrary::Load(const std::string& xmlFile )
{
this->xmlFile = xmlFile;
if( ! this->doc.LoadFile(xmlFile.c_str()))
{
throw KXmlFileException(std::string("文件: ") + xmlFile + " 无法加载, 请确认文件名!");
}
doc.ClearError();
TiXmlElement* root = doc.RootElement();//"KingBook"
if(doc.Error())
{
throw KXmlFileException(doc.ErrorDesc());
}
// 初始化 两个根节点
this->classRoot = root->FirstChild("BookClasses");
if(this->classRoot == NULL)
{
throw KXmlFileException(std::string("文件: ") + xmlFile + "格式错误。没有\"BookClasses\"节点");
}
this->bookRoot = root->FirstChild("Books");
if(this->bookRoot == NULL)
{
throw KXmlFileException(std::string("文件: ") + xmlFile + "格式错误。没有\"Books\"节点");
}
return 0;
}
/// <summary>构造函数:使用一个书库的数据文件初始化</summary>
/// <param name="xmlFile">[IN]数据文件的路径</param>
/// <exception cref="KXmlFileException">文件xmlFile无法加载, 可能文件路径问题</exception>
/// <exception cref="KXmlFileException">文件xmlFile格式错误</exception>
/// <remarks>这个数据文件必须是XML格式的文件
/// </remarks>
BookLibrary::BookLibrary(const std::string& xmlFile)
{
this->xmlFile = xmlFile;
if( ! this->doc.LoadFile(xmlFile.c_str()))
{
throw KXmlFileException(std::string("文件: ") + xmlFile + " 无法加载, 请确认文件名!");
}
doc.ClearError();
TiXmlElement* root = doc.RootElement();//"KingBook"
if(doc.Error())
{
throw KXmlFileException(doc.ErrorDesc());
}
// 初始化 两个根节点
this->classRoot = root->FirstChild("BookClasses");
if(this->classRoot == NULL)
{
throw KXmlFileException(std::string("文件: ") + xmlFile + "格式错误。没有\"BookClasses\"节点");
}
this->bookRoot = root->FirstChild("Books");
if(this->bookRoot == NULL)
{
throw KXmlFileException(std::string("文件: ") + xmlFile + "格式错误。没有\"Books\"节点");
}
}
/// <summary>使用当前XML文档保存图书数据库</summary>
/// <returns>成功返回0, 失败返回其他值</returns>
/// <exception>NULL</exception>
/// <remarks>如果没有加载图书数据库, 失败.<br/>
/// 保存过程中可能有错误发生.
/// </remarks>
int BookLibrary::Save()
{
if(this->xmlFile.size() == 0)
return 1;
if( ! this->doc.SaveFile())
return 1;
return 0;
}
/// <summary>使用新的文件, 保存图书数据库, 类似于"另存为".</summary>
/// <param name="xmlFile">新的文件名, 绝对路径</param>
/// <returns>成功返回0, 失败返回其他值</returns>
/// <exception>NULL</exception>
/// <remarks>如果没有加载图书数据库, 失败.<br/>
/// 保存过程中可能有错误发生.
/// </remarks>
int BookLibrary::Save(const std::string& xmlFile)
{
if(this->xmlFile.size() == 0)
return 1;
if( ! this->doc.SaveFile(xmlFile))
return 1;
return 0;
}
/// <summary>添加新电子书</summary>
/// <param name="bookCls">[IN]图书种类的对象(该对象包含了一个id),新书将添加到这个种类</param>
/// <param name="book">[IN]新的电子书</param>
/// <returns>成功返回 0;失败返回 其他.</returns>
/// <exception cref="KXmlFileException">没有相应的图书分类</exception>
/// <exception cref="KXmlFileException">无法添加</exception>
/// <remarks>失败原因:BookLibrary 没有初始化返回 1;
/// </remarks>
int BookLibrary::AddNewBook(const BookObject& bookCls,
const Book& book)
{//TODO:2006年10月28日 23:09:28
if(bookRoot == NULL)
return 1;
if(classRoot == NULL)
return 1;
// 查找分类节点
TiXmlElement* pClassElem = NULL;
pClassElem = this->FindBookClass(this->classRoot->ToElement(), bookCls.GetID());
if(pClassElem == NULL)
{
throw KXmlFileException("没有i指定的图书分类!");
}
// 构造图书节点
// 1 用于分类,在<BookClass> 下, 名为<BookItem>
// 2 用于存储,在<Books> 下, 名为<Book>
// 1
TiXmlElement bookItem("BookItem");
bookItem.SetAttribute("id", book.GetID());
// 2
TiXmlElement bookNode("Book");
if(0 != book.SaveToXml(&bookNode))
{
throw KXmlFileException(std::string("无法添加") + book.GetName());
}
// 插入
pClassElem->InsertEndChild(bookItem);
if(NULL == this->bookRoot->InsertEndChild(bookNode))
{
throw KXmlFileException(std::string("无法添加") + book.GetName());
}
/// / 更新数据文件
//if(! this->doc.SaveFile())
//{
// throw KXmlFileException("更新数据文件失败");
//}
return 0;
}
/// <summary>删除电子书</summary>
/// <param name="book">需要删除的图书</param>
/// <returns>成功返回0; 失败返回 其他值</returns>
/// <exception cref="KXmlFileException">无法删除指定书:没有指定的书</exception>
/// <exception cref="KXmlFileException">无法删除指定书:删除失败</exception>
/// <remarks></remarks>
int BookLibrary::DeleteBook(const BookObject& book)
{
if(bookRoot == NULL)
return 1;
if(classRoot == NULL)
return 1;
//TODO:两步:删除图书分类中的项(分类,收藏夹,最近浏览) ; 删除图书信息节点.
// 1. 删除图书分类中的项
TiXmlElement* bookElem = this->FindClassOfBook((TiXmlElement*)this->classRoot, book.GetID());
while(bookElem != NULL)
{
TiXmlNode* parentNode = bookElem->Parent();
if(parentNode != NULL)
{
parentNode->RemoveChild(bookElem);
}
bookElem = this->FindClassOfBook((TiXmlElement*)this->classRoot, book.GetID());
}
// 2: 删除图书信息节点.
// 2.1查找
TiXmlNode* child = bookRoot->FirstChild("Book");
for(; child != NULL; child = child->NextSibling("Book"))
{
if(book.GetID() == std::string(child->ToElement()->Attribute("id")))
{
break; // 找到 指定的相应的电子书
}
}
if(NULL == child) // 没有相应的电子书
{
throw KXmlFileException("无法删除指定书:没有指定的书");
}
// 2.2 删除
if(! bookRoot->RemoveChild(child))
{
throw KXmlFileException("无法删除指定书:删除失败");
}
return 0;
}
/// <summary>修改电子书的信息, 不能修改图书的id</summary>
/// <param name="oldBook">[IN]即将修改信息的电子书</param>
/// <param name="newBookInfo">[IN]新的信息, 这些信息将保存到oldBook里.</param>
/// <returns>成功返回0; 失败返回 其他值</returns>
/// <exception cref="KXmlFileException">没有指定的书</exception>
/// <exception cref="KXmlFileException">无法修改指定书的信息</exception>
/// <remarks>一本电子书一旦加入到书库后, 他的id是不可修改的.
/// 失败原因:BookLibrary 没有初始化返回 1;
/// </remarks>
int BookLibrary::ModifyBookInfo(const BookObject& oldBook,
const Book& newBookInfo)
{
int hr = -1;
if(bookRoot == NULL)
return 1;
//修改电子书的信息
TiXmlNode* child = bookRoot->FirstChild("Book");
for(; child != NULL; child = child->NextSibling("Book"))
{
if(oldBook.GetID() == std::string(child->ToElement()->Attribute("id")))
{
break; // 找到 指定的相应的电子书
}
}
if(NULL == child) // 没有相应的电子书
{
throw KXmlFileException("没有指定的书");
}
// 组合 id 和信息
Book bookTmp(newBookInfo);
bookTmp.SetID(oldBook.GetID());
// 保存到xmlDom节点
TiXmlElement newChild("Book");
if(bookTmp.SaveToXml(&newChild) != 0 )
{
throw KXmlFileException("无法修改指定书的信息");
}
// 更新XmlDom
if(NULL == bookRoot->ReplaceChild(child, newChild))
{
throw KXmlFileException("无法修改指定书的信息");
}
return 0;
}
//TODO: 修改电子书的分类(移动)
int BookLibrary::MoveBook(const BookObject& book,
const BookObject& newBookCls)
{
return 0;
}
/// <summary>得到指定电子书的(详细)信息。一般情况下,显示书的名称,作者,摘要,
/// 要得到使用该函数得到详细信息.</summary>
/// <param name="book">[IN]得到这个对象的详细信息</param>
/// <param name="bookInfo">[OUT]详细信息将保存到这个对象里</param>
/// <returns>成功返回0; 失败返回 其他值</returns>
/// <exception cref="KXmlFileException">没有指定的书</exception>
/// <exception cref="KXmlFileException">调用的函数会跑出异常</exception>
/// <remarks>
/// 失败原因:BookLibrary 没有初始化返回 1
/// </remarks>
int BookLibrary::GetBookInfo(const BookObject& book, Book &bookInfo)
{
if(bookRoot == NULL)
return 1;
TiXmlNode* child = bookRoot->FirstChild("Book");
for(; child != NULL; child = child->NextSibling("Book"))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -