Introduction
The C++11 version of my popular XML Library (http://www.codeproject.com/Articles/18732/XML-Include-a-Flexible-Parser-in-Your-C-Applicatio) with a cleaner interface, within one .h file which can be used in precompiled headers as well.
BXML
A class to represent binary data in XML. Can set/get from Base64
.
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
- Constructor can initialize from:
- Value:
XMLContent v("n");
- Another Variable:
XMLContent v2 = v;
- Enhancements
- Templates to set and get:
v3.SetFormattedValue<int>("%d",5);
v3.SetFormattedValue<const char*>("%s","hello");
auto j = v3.GetFormattedValue<int>("%d"); // using sscanf, j = int.
- Serialization to
string
with or without encoding.
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();
bool operator==(const XMLContent& t) const;
operator const string& () const;
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);
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;
virtual string Serialize(bool NoEnc = false) const;
};
XMLComment, XMLCData, XMLDocType and XMLVariable/XMLAttribute
All these inherit from XMLContent
. In addition, XMLVariable
includes methods to set/get the attribute name. With the same functions, all these classes can now, for example, set binary values for their contents.
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);
const string& SetName(const char* VN);
const string& SetName(const string& VN);
void Clear();
XMLVariable& operator =(const char* s);
XMLVariable& operator =(const string& s);
bool operator <(const XMLVariable& x) const;
bool operator ==(const XMLVariable& x) const;
bool operator ==(const char* x) const;
const string& XMLVariable::GetName() const;
size_t MemoryUsage() const;
virtual string Serialize(bool NoEnc = false) const;
};
XMLHeader
The XML header class contains the standalone, version and encoding as attributes, so you can access them via XMLVariable
.
XMLElement
XMLElement
features:
shared_ptr
arrays of all child elements, contents, comments, cdatas, attributes.
vector<shared_ptr<XMLElement>> v = el.GetChildren();
- Access to elements via operator
[]
and an index:
el[0].vv["animal"] = "rabbit";
- Access via operator
[]
and a string
, creates children if they do not exist:
el["hello"]["there"] = "<there v=\"test\">";
- Access to attributes via
v()
with index or variable name, or with vv()
for the full XMLVariable
:
string g = el.v("t");
- Copy or mirror:
XMLElement e1 = "<e v=\"hi\">";
XMLElement e2 = e1;
XMLElement e3 = e1.Mirror();
e1.vv("v") = "hello";
- Access to parent using
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; }
bool operator==(const XMLElement& t) const;
bool operator <(const XMLElement& x) const;
XMLElement& operator =(const char*);
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;
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);
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;
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);
size_t RemoveAllElements();
size_t RemoveElement(size_t i);
shared_ptr<XMLElement> RemoveElementAndKeep(size_t i) throw(XML_ERROR);
void clear();
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
- Construct empty, from ansi/unicode file, from memory.
- Save to memory, file or FILE*.
- operator = to parse text.
- Contains an
XMLHeader
, an XMLDocType
, a vector of XMLComment
and the root XMLElement
.
class XML
{
private:
bool UnicodeFile = false;
string fname;
XMLHeader hdr;
XMLDocType doctype;
vector<shared_ptr<XMLComment>> hdrcomments;
XMLElement root;
public:
XML();
XML(const char* file);
XML(const wchar_t* file);
XML(const char* mem,size_t l);
void operator =(const char* d);
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;
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);
XMLElement& XML::GetRootElement();
XMLHeader& XML::GetHeader();
size_t XML::MemoryUsage();
void SetRootElement(XMLElement& newroot);
void SetHeader(const XMLHeader& h);
void Clear();
void Version(XML_VERSION_INFO* x);
string Serialize(bool NoEnc = false) const;
};
Example sample.xml
="1.0"="yes"
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<catalog>
<product description="Cardigan Sweater" product_image="cardigan.jpg" >
<catalog_item gender="Men's">
<item_number>QWZ5671</item_number>
<price>39.95</price>
<![CDATA[
<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>
Parse it:
using namespace XML3;
XML x("sample.xml");
auto&root = x.GetRootElement();
string v1 = root["product"].v(0); string v2 = root["product"]["catalog_item"]["price"].GetContent(); string v3 = root.AddVariable("n","val").Serialize();
JSON
The helper XML3::JsonParser(XMLElement* r,const char* txt)
helps you parse JSON into an XMLElement
. It creates a <json>
element inside r
, and puts all JSON data there. Note that this is not a complete implementation of JSON.
History
- 04/09/2018 Prepare for canonicalization and XAdES-T
- 24/12/2015 Fixed case when
<?xml?>
in not closing the header - 04/11/2015 Fixed trimming in
XMLContent
- 29/10/2015 Removed MIME code and used Win32 API instead, also fixed GCC incompatibilities
- 19/09/2015 Fixed case when
<?xml?>
without other spaces - 31/07/2015 Simplified BXML by using
vector<char>
- 13/07/2015 Added copy + move constructor to XML
- 09/07/2015 More move semantics in
BXML
and XMLElement
- 06/07/2015 Added move semantics for
XMLElement Insert
/Add
element and fixed XMLVariable
bug. - 14/06/2015 Bugfixes and speed enhancements
- 06/06/2015 First release