XML++ 版本 3:我的 XML 库的 C++11 更新






4.90/5 (33投票s)
我对心爱的库的更新。 单头文件。
- Github: https://github.com/WindowsNT/xml
引言
我的流行的 XML 库(https://codeproject.org.cn/Articles/18732/XML-Include-a-Flexible-Parser-in-Your-C-Applicatio)的 C++11 版本,具有更简洁的接口,包含在一个 .h 文件中,也可以用于预编译头。
BXML
一个用于在 XML 中表示二进制数据的类。 可以从 Base64
设置/获取。
// BXML
class BXML
{
private:
vector<char> d;
public:
BXML(size_t s = 0);
bool operator ==(const BXML& b2);
void ToB(string& s);
void FromB(const char* ba);
operator const char*() const;
operator char*();
const char* p() const;
char* p();
size_t size() const;
void clear();
void reset();
void Ensure(size_t news);
void Resize(size_t news);
void AddResize(size_t More);
};
XMLContent
- 构造函数可以从以下内容初始化
- 值
XMLContent v("n");
- 另一个变量
XMLContent v2 = v;
- 值
- 增强功能
- 设置值
v2 = "hello";
- 二进制内容
v2.SetBinaryData("\0\0\0",3);
- operator const char*()
string z = v2;
- 设置值
- 用于设置和获取的模板
v3.SetFormattedValue<int>("%d",5);
v3.SetFormattedValue<const char*>("%s","hello");
auto j = v3.GetFormattedValue<int>("%d"); // 使用 sscanf,j = int。
- 序列化为
string
,有或没有编码。class XMLContent { protected: string v; size_t ep = 0; public: XMLContent(); XMLContent(size_t ElementPosition,const char* ht); XMLContent(size_t ElementPosition,const wchar_t* ht); size_t MemoryUsage(); // Operators bool operator==(const XMLContent& t) const; operator const string& () const; // Sets const string& SetFormattedValue(const char* fmt,...); template <typename T> const string& SetFormattedValue(const char* fmt,T ty) { unique_ptr<char> t(new char[10000]); sprintf_s(t.get(),fmt,10000,ty); SetValue(t); return v; } XMLContent& operator =(const char* s); XMLContent& operator =(const string& s); const string& SetBinaryValue(const char* data,size_t len); void SetValue(const char* VV); void SetValue(const string& VV); void Clear(); void SetEP(size_t epp); // Gets BXML GetBinaryValue() const; template <typename T> T GetFormattedValue(const char* fmt) const { T x; sscanf(v.c_str(),fmt,&x); return x; } const string& GetValue() const; size_t GetEP() const; // Serialization virtual string Serialize(bool NoEnc = false) const; };
XMLComment、XMLCData、XMLDocType 和 XMLVariable/XMLAttribute
所有这些都继承自 XMLContent
。 此外,XMLVariable
包含用于设置/获取属性名称的方法。 借助相同的函数,所有这些类现在都可以,例如,为其内容设置二进制值。
class XMLVariable : public XMLContent
{
private:
string n;
bool tmp = false;
public:
explicit XMLVariable();
explicit XMLVariable(const char* nn,const char* vv,bool Temp = false);
explicit XMLVariable::XMLVariable(const XMLVariable& h);
XMLVariable& operator =(const XMLVariable& h);
// XMLVariable& operator =(const std::initializer_list<string>& s);
const string& SetName(const char* VN);
const string& SetName(const string& VN);
void Clear();
XMLVariable& operator =(const char* s);
XMLVariable& operator =(const string& s);
// Compare
bool operator <(const XMLVariable& x) const;
bool operator ==(const XMLVariable& x) const;
bool operator ==(const char* x) const;
// Gets
const string& XMLVariable::GetName() const;
// Memory usage
size_t MemoryUsage() const;
// Serialization
virtual string Serialize(bool NoEnc = false) const;
};
XMLHeader
XML 头类包含独立、版本和编码作为属性,因此可以通过 XMLVariable
访问它们。
XMLElement
XMLElement
特性
- 所有子元素、内容、注释、CDATA、属性的
shared_ptr
数组。vector<shared_ptr<XMLElement>> v = el.GetChildren();
- 通过运算符
[]
和索引访问元素el[0].vv["animal"] = "rabbit";
- 通过运算符
[]
和string
访问,如果它们不存在则创建子元素el["hello"]["there"] = "<there v=\"test\">";
- 通过索引或变量名使用
v()
访问属性,或使用vv()
访问完整的XMLVariable
string g = el.v("t");
- 复制或镜像
XMLElement e1 = "<e v=\"hi\">"; XMLElement e2 = e1; XMLElement e3 = e1.Mirror(); e1.vv("v") = "hello"; // e3 variable is changed as well, e2 still "hi"
- 使用
XMLId
访问父元素class XMLElement { private: string el = "e"; vector<shared_ptr<XMLElement>> children; vector<shared_ptr<XMLVariable>> variables; vector<shared_ptr<XMLContent>> contents; vector<shared_ptr<XMLComment>> comments; vector<shared_ptr<XMLCData>> cdatas; unsigned long long param = 0; XMLId parent = 0; XMLId id; static void CloneMirror(XMLElement& to,const XMLElement& from); public: XMLElement(); XMLElement(const char*); XMLElement(const XMLElement&); XMLElement(XMLElement&&); XMLElement Mirror() const; const vector<shared_ptr<XMLComment>>& XMLElement::GetComments() const { return comments; } const vector<shared_ptr<XMLElement>>& XMLElement::GetChildren() const { return children; } const vector<shared_ptr<XMLVariable>>& XMLElement::GetVariables() const { return variables; } const vector<shared_ptr<XMLCData>>& XMLElement::GetCDatas() const { return cdatas; } const vector<shared_ptr<XMLContent>>& XMLElement::GetContents() const { return contents; } vector<shared_ptr<XMLComment>>& XMLElement::GetComments() { return comments; } vector<shared_ptr<XMLElement>>& XMLElement::GetChildren() { return children; } vector<shared_ptr<XMLVariable>>& XMLElement::GetVariables() { return variables; } vector<shared_ptr<XMLCData>>& XMLElement::GetCDatas() { return cdatas; } vector<shared_ptr<XMLContent>>& XMLElement::GetContents() { return contents; } // Operators bool operator==(const XMLElement& t) const; bool operator <(const XMLElement& x) const; XMLElement& operator =(const char*); // Gets XMLElement& operator [](size_t idx); XMLElement& operator [](const char* elm); const string& v(size_t idx) const; const string& v(const char* nn); string vd(const char*nn,const char*def = 0); string vd(const char*nn,const char*def = 0) const; string Content() const; XMLVariable& vv(const char* nn); unsigned long long GetElementParam() const; const string& GetElementName() const; void GetAllChildren(vector<shared_ptr<XMLElement>>& ch) const; shared_ptr<XMLElement> GetParent(shared_ptr<XMLElement> r) const; XMLElement* GetParent(XMLElement* r) const; size_t GetElementIndex(const XMLElement& e) const; // Sets void SetElementName(const char* x); void SetElementName(const wchar_t* x); void SetElementParam(unsigned long long p); void SortElements(std::function<bool(const shared_ptr<XMLElement>&e1, const shared_ptr<XMLElement>&e2)>); void SortVariables(std::function<bool(const shared_ptr<XMLVariable>&e1, const shared_ptr<XMLVariable>&e2)>); XML_ERROR XMLElement::MoveElement(size_t i,size_t y); // Find shared_ptr<XMLElement> FindElementZ(const char* n,bool ForceCreate = false); shared_ptr<XMLVariable> FindVariableZ(const char* n,bool ForceCreate = false, const char* defv = ""); shared_ptr<XMLVariable> FindVariable(const char* n) const; // Inserts shared_ptr<XMLElement> InsertElement(size_t y,const XMLElement& x); shared_ptr<XMLElement> InsertElement(size_t y,XMLElement&& x); XMLElement& AddElement(const XMLElement& c); XMLElement& AddElement(XMLElement&& c); XMLElement& AddElement(const char* n = ""); void AddElements(const std::initializer_list<string>& s); void SetVariables(const std::initializer_list<string>& s); XMLVariable& AddVariable(const char* vn = "n",const char* vv = "v",size_t p = -1); XMLVariable& AddVariable(const XMLVariable& v,size_t p = -1); XMLContent& AddContent(const char* pv,size_t ep,size_t p = -1); XMLComment& AddComment(const char* pv,size_t ep,size_t p = -1); XMLCData& AddCData(const char* pv,size_t ep,size_t p = -1); // Removals size_t RemoveAllElements(); size_t RemoveElement(size_t i); shared_ptr<XMLElement> RemoveElementAndKeep(size_t i) throw(XML_ERROR); void clear(); // Variables size_t RemoveAllVariables(); size_t RemoveVariable(size_t i); shared_ptr<XMLVariable> RemoveVariableAndKeep(size_t i) throw (XML_ERROR); string EorE(const string& s,bool N) const; string Serialize(bool NoEnc = false,size_t deep = 0) const; void Serialize(string& v,bool NoEnc = false,size_t deep = 0) const; };
XML
- 构造空元素,从 ansi/unicode 文件,从内存构造。
- 保存到内存、文件或 FILE*。
- operator = 用于解析文本。
- 包含一个
XMLHeader
、一个XMLDocType
、一个XMLComment
向量和根XMLElement
。
class XML
{
private:
bool UnicodeFile = false;
string fname;
XMLHeader hdr;
XMLDocType doctype;
vector<shared_ptr<XMLComment>> hdrcomments;
XMLElement root;
public:
// Constructors
XML();
XML(const char* file);
XML(const wchar_t* file);
XML(const char* mem,size_t l);
void operator =(const char* d);
// Savers
size_t SaveFP(FILE* fp) const;
XML_ERROR Save() const;
XML_ERROR Save(const char* f) const;
XML_ERROR Save(const wchar_t* f) const;
// Loaders
XML_PARSE ParseFile(FILE* fp);
XML_PARSE Load(const char* f);
XML_PARSE Load(const wchar_t* f);
XML_PARSE Parse(const char* m,size_t len);
// Gets
XMLElement& XML::GetRootElement();
XMLHeader& XML::GetHeader();
size_t XML::MemoryUsage();
// Sets
void SetRootElement(XMLElement& newroot);
void SetHeader(const XMLHeader& h);
void Clear();
void Version(XML_VERSION_INFO* x);
// ser
string Serialize(bool NoEnc = false) const;
};
示例 sample.xml
<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<!-- root comment 1 -->
<!-- root comment 2 -->
<catalog>
<!-- cat comment 1 -->
<product description="Cardigan Sweater" product_image="cardigan.jpg" >
<!-- pro comment 1 -->
<catalog_item gender="Men's">
<item_number>QWZ5671</item_number>
<price>39.95</price>
<![CDATA[
hohoho
dfsfd
^%$&^$*^*^#&^#$&^
]]>
<size description="Medium">
cont 1
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
cont 2
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
cont 3
</size>
<size description="Large">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
</catalog_item>
</product>
</catalog>
解析它
using namespace XML3;
XML x("sample.xml");
auto&root = x.GetRootElement();
string v1 = root["product"].v(0); // Cardigan Sweater
string v2 = root["product"]["catalog_item"]["price"].GetContent(); // 39.95
string v3 = root.AddVariable("n","val").Serialize(); // created a new variable in root, n="val"
JSON
helper XML3::JsonParser(XMLElement* r,const char* txt)
帮助您将 JSON 解析到 XMLElement
中。 它在 r
内部创建一个 <json>
元素,并将所有 JSON 数据放在那里。 请注意,这并不是 JSON 的完整实现。
历史
- 2018/09/04 准备用于规范化和 XAdES-T
- 2015/12/24 修复了
<?xml?>
未关闭头的情况 - 2015/11/04 修复了
XMLContent
中的修剪问题 - 2015/10/29 删除了 MIME 代码,并使用了 Win32 API,还修复了 GCC 不兼容问题
- 2015/09/19 修复了
<?xml?>
没有其他空格的情况 - 2015/07/31 通过使用
vector<char>
简化了 BXML - 2015/07/13 为 XML 添加了复制 + 移动构造函数
- 2015/07/09 在
BXML
和XMLElement
中添加了更多移动语义 - 2015/07/06 为
XMLElement Insert
/Add
元素添加了移动语义,并修复了XMLVariable
错误。 - 2015/06/14 错误修复和速度增强
- 2015/06/06 首次发布