Merge branch 'initial'

This commit is contained in:
d-led 2012-10-03 21:08:38 +02:00
commit 3466f66e54
17 changed files with 1538 additions and 861 deletions

22
.gitattributes vendored Normal file
View File

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,37 @@
assert(require 'pugilua')
print(pugi.version)
local doc=pugi.xml_document()
os.execute("cd")
local res=doc:load_file [[..\..\scripts\pugilua\pugilua.vcxproj]]
print(res.description)
assert(res.valid)
local node=doc:child('Project')
local node=doc:root():child('Project')
assert(node.valid)
print(node.valid)
print(node.name)
print(node.name)
local query1=doc:root():select_nodes('Project/PropertyGroup')
local query2=node:select_nodes('PropertyGroup')
assert(query1)
assert(query2)
print(query1.type,pugi.xpath_node_set.type_sorted)
query1:sort(true)
print(query1.type,pugi.xpath_node_set.type_sorted)
print(query1.size,query2.size)
n=query1.size
for i=0,n-1 do
local node=query1:get(i):node()
local attribute=query1:get(i):attribute()
print(node.valid,node.path,attribute.valid)
local a=node:first_attribute()
while a.valid do
print(a.name)
a=a:next_attribute()
end
end
----
node=doc:root():child('Project')
print(node.text)

Binary file not shown.

View File

@ -4,69 +4,575 @@
#include <luabridge.h>
#include <RefCountedPtr.h>
#include <string>
#include <iostream>
#include <sstream>
namespace pugi {
namespace lua {
static char const* version = "0.1.0";
class lxpath_node;
class lxpath_node_set;
////////////////////
static int encoding_auto = (int)pugi::encoding_auto;
static int encoding_utf8 = (int)pugi::encoding_utf8;
static int encoding_utf16_le = (int)pugi::encoding_utf16_le;
static int encoding_utf16_be = (int)pugi::encoding_utf16_be;
static int encoding_utf16 = (int)pugi::encoding_utf16;
static int encoding_utf32_le = (int)pugi::encoding_utf32_le;
static int encoding_utf32_be = (int)pugi::encoding_utf32_be;
static int encoding_utf32 = (int)pugi::encoding_utf32;
static int encoding_wchar = (int)pugi::encoding_wchar;
static int encoding_latin1 = (int)pugi::encoding_latin1;
////////////////////
static int node_null = (int)pugi::node_null;
static int node_document = (int)pugi::node_document;
static int node_element = (int)pugi::node_element;
static int node_pcdata = (int)pugi::node_pcdata;
static int node_cdata = (int)pugi::node_cdata;
static int node_comment = (int)pugi::node_comment;
static int node_pi = (int)pugi::node_pi;
static int node_declaration = (int)pugi::node_declaration;
static int node_doctype = (int)pugi::node_doctype;
////////////////////
class lxml_attribute {
public:
lxml_attribute(pugi::xml_attribute const& a):att(a) {}
lxml_attribute() {}
public:
bool valid() const { return (bool)att; }
bool empty() const { return att.empty(); }
std::string name() const { return att.name(); }
std::string value() const { return att.value(); }
double number() const { return att.as_double(); }
bool as_bool() const { return att.as_bool(); }
void set_name(char const* n) { att.set_name(n); }
void set_value(char const* v) { att.set_value(v); }
RefCountedPtr<lxml_attribute> next_attribute() const {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(att.next_attribute()));
}
RefCountedPtr<lxml_attribute> previous_attribute() const {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(att.previous_attribute()));
}
size_t hash_value() const {
return att.hash_value();
}
public: // non-lua interface
pugi::xml_attribute const& get() const {
return att;
}
private:
pugi::xml_attribute att;
};
///////////////////////
class lxml_parse_result {
public:
lxml_parse_result(pugi::xml_parse_result& r):res(r) { }
lxml_parse_result() { }
lxml_parse_result(pugi::xml_parse_result& r);
lxml_parse_result();
public:
std::string description() const {
return res.description();
std::string description() const;
bool valid() const;
int status() const {
return res.status;
}
bool valid() const {
return (bool)res;
int encoding() const {
return res.encoding;
}
ptrdiff_t offset() const {
return res.offset;
}
public:
static int status_ok() { return pugi::status_ok; }
static int status_file_not_found() { return pugi::status_file_not_found; }
static int status_io_error() { return pugi::status_io_error; }
static int status_out_of_memory() { return pugi::status_out_of_memory; }
static int status_internal_error() { return pugi::status_internal_error; }
static int status_unrecognized_tag() { return pugi::status_unrecognized_tag; }
static int status_bad_pi() { return pugi::status_bad_pi; }
static int status_bad_comment() { return pugi::status_bad_comment; }
static int status_bad_cdata() { return pugi::status_bad_cdata; }
static int status_bad_doctype() { return pugi::status_bad_doctype; }
static int status_bad_pcdata() { return pugi::status_bad_pcdata; }
static int status_bad_start_element() { return pugi::status_bad_start_element; }
static int status_bad_attribute() { return pugi::status_bad_attribute; }
static int status_bad_end_element() { return pugi::status_bad_end_element; }
static int status_end_element_mismatch() { return pugi::status_end_element_mismatch; }
private:
pugi::xml_parse_result res;
};
///////////////
class lxml_node {
public:
lxml_node(pugi::xml_node& n):node(n){}
lxml_node() { }
lxml_node(pugi::xml_node const& n);
lxml_node();
public:
bool valid() const {
return (bool)node;
}
bool valid() const;
RefCountedPtr<lxml_node> child(char const* name) {
return RefCountedPtr<lxml_node>(new lxml_node(node.child(name)));
}
std::string name() const;
std::string value() const;
std::string name() const {
return node.name();
}
bool empty() const;
int type() const;
RefCountedPtr<lxml_attribute> first_attribute() const;
RefCountedPtr<lxml_attribute> last_attribute() const;
RefCountedPtr<lxml_node> first_child() const;
RefCountedPtr<lxml_node> last_child() const;
RefCountedPtr<lxml_node> parent() const;
RefCountedPtr<lxml_node> root() const;
RefCountedPtr<lxml_node> child(char const* name) const;
RefCountedPtr<lxml_attribute> attribute(char const* name) const;
RefCountedPtr<lxml_node> next() const;
RefCountedPtr<lxml_node> previous() const;
RefCountedPtr<lxml_node> next_sibling(char const* name) const;
RefCountedPtr<lxml_node> previous_sibling(char const* name) const;
std::string child_value(char const* name) const;
bool set_name(char const* rhs);
bool set_value(char const* rhs);
RefCountedPtr<lxml_attribute> append_attribute(const char* name);
RefCountedPtr<lxml_attribute> prepend_attribute(const char* name);
RefCountedPtr<lxml_attribute> insert_attribute_after(const char* name, RefCountedPtr<lxml_attribute> attr);
RefCountedPtr<lxml_attribute> insert_attribute_before(const char* name, RefCountedPtr<lxml_attribute> attr);
RefCountedPtr<lxml_attribute> append_attribute_copy(RefCountedPtr<lxml_attribute> proto);
RefCountedPtr<lxml_attribute> prepend_attribute_copy(RefCountedPtr<lxml_attribute> proto);
RefCountedPtr<lxml_attribute> insert_attribute_copy_after(RefCountedPtr<lxml_attribute> proto, RefCountedPtr<lxml_attribute> attr);
RefCountedPtr<lxml_attribute> insert_attribute_copy_before(RefCountedPtr<lxml_attribute> proto, RefCountedPtr<lxml_attribute> attr);
RefCountedPtr<lxml_node> append(int type);
RefCountedPtr<lxml_node> prepend(int type);
RefCountedPtr<lxml_node> insert_after(int type, RefCountedPtr<lxml_node> _node);
RefCountedPtr<lxml_node> insert_before(int type, RefCountedPtr<lxml_node> _node);
RefCountedPtr<lxml_node> append_child(const char* name);
RefCountedPtr<lxml_node> prepend_child(const char* name);
RefCountedPtr<lxml_node> insert_child_after(const char* name, RefCountedPtr<lxml_node> _node);
RefCountedPtr<lxml_node> insert_child_before(const char* name, RefCountedPtr<lxml_node> _node);
RefCountedPtr<lxml_node> append_copy(RefCountedPtr<lxml_node> proto);
RefCountedPtr<lxml_node> prepend_copy(RefCountedPtr<lxml_node> proto);
RefCountedPtr<lxml_node> insert_copy_after(RefCountedPtr<lxml_node> proto, RefCountedPtr<lxml_node> _node);
RefCountedPtr<lxml_node> insert_copy_before(RefCountedPtr<lxml_node> proto, RefCountedPtr<lxml_node> _node);
bool remove_attribute(RefCountedPtr<lxml_attribute> a);
bool remove_attribute_by_name(const char* name);
bool remove_child(RefCountedPtr<lxml_node> n);
bool remove_child_by_name(const char* name);
RefCountedPtr<lxml_node> find_child_by_name_and_attribute(const char* name, const char* attr_name, const char* attr_value) const;
RefCountedPtr<lxml_node> find_child_by_attribute(const char* attr_name, const char* attr_value) const;
std::string path() const;
RefCountedPtr<lxml_node> first_element_by_path(const char* path) const;
RefCountedPtr<lxpath_node> select_single_node(const char* query) const;
RefCountedPtr<lxpath_node_set> select_nodes(char const* query) const;
std::string text() const;
//todo: text(), xml_tree_walker somehow
public: // non-lua interface
pugi::xml_node const& get() const;
private:
pugi::xml_node node;
};
///////////////////
class lxml_document {
public:
RefCountedPtr<lxml_parse_result> load_file(char const* path) {
return RefCountedPtr<lxml_parse_result>(new lxml_parse_result(doc.load_file(path)));
}
RefCountedPtr<lxml_node> lxml_document::root() const;
// redundant, but defined due to composition up to now
RefCountedPtr<lxml_node> child(char const* name) {
return RefCountedPtr<lxml_node>(new lxml_node(doc.child(name)));
}
bool valid() const;
bool valid() const {
return (bool)doc;
}
void reset();
RefCountedPtr<lxml_parse_result> load_file(char const* path);
RefCountedPtr<lxml_parse_result> load(char const* contents);
bool save_file(char const* path) const;
private:
pugi::xml_document doc;
};
/////////////////
class lxpath_node {
public:
lxpath_node(pugi::xpath_node const& n);
lxpath_node();
bool valid() const;
RefCountedPtr<lxml_node> node() const;
RefCountedPtr<lxml_attribute> attribute() const;
private:
pugi::xpath_node _node;
};
/////////////////////
class lxpath_node_set {
public:
lxpath_node_set(pugi::xpath_node_set& s);
lxpath_node_set();
public:
int type() const;
size_t size() const;
// todo: think if 1..size is a better convention for lua
RefCountedPtr<lxpath_node> get(size_t i);
void sort(bool reverse);
public:
// enums
static int type_unsorted () { return pugi::xpath_node_set::type_unsorted; }
static int type_sorted () { return pugi::xpath_node_set::type_sorted; }
static int type_sorted_reverse () { return pugi::xpath_node_set::type_sorted_reverse; }
private:
pugi::xpath_node_set node_set;
};
}
}
namespace pugi {
namespace lua {
///////////////////////
lxml_parse_result::lxml_parse_result(pugi::xml_parse_result& r):res(r) { }
lxml_parse_result::lxml_parse_result() { }
std::string lxml_parse_result::description() const {
return res.description();
}
bool lxml_parse_result::valid() const {
return (bool)res;
}
///////////////
lxml_node::lxml_node(pugi::xml_node const& n):node(n){}
lxml_node::lxml_node() { }
pugi::xml_node const& lxml_node::get() const {
return node;
}
bool lxml_node::valid() const {
return (bool)node;
}
RefCountedPtr<lxml_node> lxml_node::child(char const* name) const {
return RefCountedPtr<lxml_node>(new lxml_node(node.child(name)));
}
std::string lxml_node::name() const {
return node.name();
}
std::string lxml_node::value() const {
return node.value();
}
RefCountedPtr<lxpath_node_set> lxml_node::select_nodes(char const* query) const {
try {
return RefCountedPtr<lxpath_node_set>(new lxpath_node_set(node.select_nodes(query)));
} catch (pugi::xpath_exception const& e) {
std::cerr<<"Error: "<<e.what()<<std::endl;
return RefCountedPtr<lxpath_node_set>(new lxpath_node_set());
}
}
bool lxml_node::empty() const {
return node.empty();
}
int lxml_node::type() const {
return node.type();
}
RefCountedPtr<lxml_attribute> lxml_node::first_attribute() const {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.first_attribute()));
}
RefCountedPtr<lxml_attribute> lxml_node::last_attribute() const {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.last_attribute()));
}
RefCountedPtr<lxml_node> lxml_node::first_child() const {
return RefCountedPtr<lxml_node>(new lxml_node(node.first_child()));
}
RefCountedPtr<lxml_node> lxml_node::last_child() const {
return RefCountedPtr<lxml_node>(new lxml_node(node.last_child()));
}
RefCountedPtr<lxml_node> lxml_node::parent() const {
return RefCountedPtr<lxml_node>(new lxml_node(node.parent()));
}
RefCountedPtr<lxml_node> lxml_node::root() const {
return RefCountedPtr<lxml_node>(new lxml_node(node.root()));
}
RefCountedPtr<lxml_attribute> lxml_node::attribute(char const* name) const {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.attribute(name)));
}
RefCountedPtr<lxml_node> lxml_node::next() const {
return RefCountedPtr<lxml_node>(new lxml_node(node.next_sibling()));
}
RefCountedPtr<lxml_node> lxml_node::previous() const {
return RefCountedPtr<lxml_node>(new lxml_node(node.previous_sibling()));
}
RefCountedPtr<lxml_node> lxml_node::next_sibling(char const* name) const {
return RefCountedPtr<lxml_node>(new lxml_node(node.next_sibling(name)));
}
RefCountedPtr<lxml_node> lxml_node::previous_sibling(char const* name) const {
return RefCountedPtr<lxml_node>(new lxml_node(node.previous_sibling(name)));
}
std::string lxml_node::child_value(char const* name) const {
return node.child_value(name);
}
bool lxml_node::set_name(char const* rhs) {
return node.set_name(rhs);
}
bool lxml_node::set_value(char const* rhs) {
return node.set_value(rhs);
}
RefCountedPtr<lxml_attribute> lxml_node::append_attribute(const char* name) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.append_attribute(name)));
}
RefCountedPtr<lxml_attribute> lxml_node::prepend_attribute(const char* name) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.prepend_attribute(name)));
}
RefCountedPtr<lxml_attribute> lxml_node::insert_attribute_after(const char* name, RefCountedPtr<lxml_attribute> attr) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.insert_attribute_after(name,attr->get())));
}
RefCountedPtr<lxml_attribute> lxml_node::insert_attribute_before(const char* name, RefCountedPtr<lxml_attribute> attr) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.insert_attribute_before(name,attr->get())));
}
RefCountedPtr<lxml_attribute> lxml_node::append_attribute_copy(RefCountedPtr<lxml_attribute> proto) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.append_copy(proto->get())));
}
RefCountedPtr<lxml_attribute> lxml_node::prepend_attribute_copy(RefCountedPtr<lxml_attribute> proto) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.prepend_copy(proto->get())));
}
RefCountedPtr<lxml_attribute> lxml_node::insert_attribute_copy_after(RefCountedPtr<lxml_attribute> proto, RefCountedPtr<lxml_attribute> attr) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.insert_copy_after(proto->get(),attr->get())));
}
RefCountedPtr<lxml_attribute> lxml_node::insert_attribute_copy_before(RefCountedPtr<lxml_attribute> proto, RefCountedPtr<lxml_attribute> attr) {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(node.insert_copy_before(proto->get(),attr->get())));
}
RefCountedPtr<lxml_node> lxml_node::append(int type) {
return RefCountedPtr<lxml_node>(new lxml_node(node.append_child((xml_node_type)type)));
}
RefCountedPtr<lxml_node> lxml_node::prepend(int type) {
return RefCountedPtr<lxml_node>(new lxml_node(node.prepend_child((xml_node_type)type)));
}
RefCountedPtr<lxml_node> lxml_node::insert_after(int type, RefCountedPtr<lxml_node> _node) {
return RefCountedPtr<lxml_node>(new lxml_node(node.insert_child_after((xml_node_type)type,_node->get())));
}
RefCountedPtr<lxml_node> lxml_node::insert_before(int type, RefCountedPtr<lxml_node> _node) {
return RefCountedPtr<lxml_node>(new lxml_node(node.insert_child_before((xml_node_type)type,_node->get())));
}
RefCountedPtr<lxml_node> lxml_node::append_child(const char* name) {
return RefCountedPtr<lxml_node>(new lxml_node(node.append_child(name)));
}
RefCountedPtr<lxml_node> lxml_node::prepend_child(const char* name) {
return RefCountedPtr<lxml_node>(new lxml_node(node.prepend_child(name)));
}
RefCountedPtr<lxml_node> lxml_node::insert_child_after(const char* name, RefCountedPtr<lxml_node> _node) {
return RefCountedPtr<lxml_node>(new lxml_node(node.insert_child_after(name,_node->get())));
}
RefCountedPtr<lxml_node> lxml_node::insert_child_before(const char* name, RefCountedPtr<lxml_node> _node) {
return RefCountedPtr<lxml_node>(new lxml_node(node.insert_child_before(name,_node->get())));
}
RefCountedPtr<lxml_node> lxml_node::append_copy(RefCountedPtr<lxml_node> proto) {
return RefCountedPtr<lxml_node>(new lxml_node(node.append_copy(proto->get())));
}
RefCountedPtr<lxml_node> lxml_node::prepend_copy(RefCountedPtr<lxml_node> proto) {
return RefCountedPtr<lxml_node>(new lxml_node(node.prepend_copy(proto->get())));
}
RefCountedPtr<lxml_node> lxml_node::insert_copy_after(RefCountedPtr<lxml_node> proto, RefCountedPtr<lxml_node> _node) {
return RefCountedPtr<lxml_node>(new lxml_node(node.insert_copy_after(proto->get(),_node->get())));
}
RefCountedPtr<lxml_node> lxml_node::insert_copy_before(RefCountedPtr<lxml_node> proto, RefCountedPtr<lxml_node> _node) {
return RefCountedPtr<lxml_node>(new lxml_node(node.insert_copy_before(proto->get(),_node->get())));
}
bool lxml_node::remove_attribute(RefCountedPtr<lxml_attribute> a) {
return node.remove_attribute(a->get());
}
bool lxml_node::remove_attribute_by_name(const char* name) {
return node.remove_attribute(name);
}
bool lxml_node::remove_child(RefCountedPtr<lxml_node> n) {
return node.remove_child(n->get());
}
bool lxml_node::remove_child_by_name(const char* name) {
return node.remove_child(name);
}
RefCountedPtr<lxml_node> lxml_node::find_child_by_name_and_attribute(const char* name, const char* attr_name, const char* attr_value) const {
return RefCountedPtr<lxml_node>(new lxml_node(node.find_child_by_attribute(name,attr_name,attr_value)));
}
RefCountedPtr<lxml_node> lxml_node::find_child_by_attribute(const char* attr_name, const char* attr_value) const {
return RefCountedPtr<lxml_node>(new lxml_node(node.find_child_by_attribute(attr_name,attr_name,attr_value)));
}
std::string lxml_node::path() const {
return node.path();
}
RefCountedPtr<lxml_node> lxml_node::first_element_by_path(const char* path) const {
return RefCountedPtr<lxml_node>(new lxml_node(node.first_element_by_path(path)));
}
RefCountedPtr<lxpath_node> lxml_node::select_single_node(char const* query) const {
try {
return RefCountedPtr<lxpath_node>(new lxpath_node(node.select_single_node(query)));
} catch (pugi::xpath_exception const& e) {
std::cerr<<"Error: "<<e.what()<<std::endl;
return RefCountedPtr<lxpath_node>(new lxpath_node());
}
}
std::string lxml_node::text() const {
std::stringstream ss;
node.print(ss);
return ss.str();
}
///////////////////
RefCountedPtr<lxml_parse_result> lxml_document::load_file(char const* path) {
return RefCountedPtr<lxml_parse_result>(new lxml_parse_result(doc.load_file(path)));
}
RefCountedPtr<lxml_node> lxml_document::root() const {
return RefCountedPtr<lxml_node>(new lxml_node(pugi::xml_node(doc)));
}
bool lxml_document::valid() const {
return (bool)doc;
}
void lxml_document::reset() {
doc.reset();
}
RefCountedPtr<lxml_parse_result> lxml_document::load(char const* contents) {
return RefCountedPtr<lxml_parse_result>(new lxml_parse_result(doc.load(contents)));
}
bool lxml_document::save_file(char const* path) const {
return doc.save_file(path);
}
//////////////////////
lxpath_node::lxpath_node(pugi::xpath_node const& n):_node(n){}
lxpath_node::lxpath_node() { }
bool lxpath_node::valid() const {
return (bool)_node;
}
RefCountedPtr<lxml_node> lxpath_node::node() const {
return RefCountedPtr<lxml_node>(new lxml_node(_node.node()));
}
RefCountedPtr<lxml_attribute> lxpath_node::attribute() const {
return RefCountedPtr<lxml_attribute>(new lxml_attribute(_node.attribute()));
}
/////////////////////
lxpath_node_set::lxpath_node_set(pugi::xpath_node_set& s):node_set(s) { }
lxpath_node_set::lxpath_node_set() { }
int lxpath_node_set::type() const {
return node_set.type();
}
size_t lxpath_node_set::size() const {
return node_set.size();
}
RefCountedPtr<lxpath_node> lxpath_node_set::get(size_t i) {
return RefCountedPtr<lxpath_node>(new lxpath_node(node_set[i]));
}
void lxpath_node_set::sort(bool reverse) {
node_set.sort(reverse);
}
}
}
@ -75,24 +581,148 @@ void register_pugilua (lua_State* L) {
luabridge::getGlobalNamespace(L)
.beginNamespace("pugi")
.addVariable("version",&version,false)
.addVariable("encoding_auto",&encoding_auto,false)
.addVariable("encoding_utf8",&encoding_utf8,false)
.addVariable("encoding_utf16_le",&encoding_utf16_le,false)
.addVariable("encoding_utf16_be",&encoding_utf16_be,false)
.addVariable("encoding_utf16",&encoding_utf16,false)
.addVariable("encoding_utf32_le",&encoding_utf32_le,false)
.addVariable("encoding_utf32_be",&encoding_utf32_be,false)
.addVariable("encoding_utf32",&encoding_utf32,false)
.addVariable("encoding_wchar",&encoding_wchar,false)
.addVariable("encoding_latin1",&encoding_latin1,false)
.addVariable("node_null",&node_null,false)
.addVariable("node_document",&node_document,false)
.addVariable("node_element",&node_element,false)
.addVariable("node_pcdata",&node_pcdata,false)
.addVariable("node_cdata",&node_cdata,false)
.addVariable("node_comment",&node_comment,false)
.addVariable("node_pi",&node_pi,false)
.addVariable("node_declaration",&node_declaration,false)
.addVariable("node_doctype",&node_doctype,false)
.beginClass<lxml_attribute>("xml_attribute")
.addConstructor<void (*)()>()
.addProperty("valid",&lxml_attribute::valid)
.addProperty("empty",&lxml_attribute::empty)
.addProperty("name",&lxml_attribute::name)
.addProperty("value",&lxml_attribute::value)
.addProperty("number",&lxml_attribute::number)
.addProperty("bool",&lxml_attribute::as_bool)
.addProperty("hash_value",&lxml_attribute::hash_value)
.addFunction("set_name",&lxml_attribute::set_name)
.addFunction("set_value",&lxml_attribute::set_value)
.addFunction("next_attribute",&lxml_attribute::next_attribute)
.addFunction("previous_attribute",&lxml_attribute::previous_attribute)
.endClass()
.beginClass<lxml_parse_result>("xml_parse_result")
.addConstructor<void (*)()>()
.addProperty("description",&lxml_parse_result::description)
.addProperty("valid",&lxml_parse_result::valid)
.addProperty("status",&lxml_parse_result::status)
.addProperty("encoding",&lxml_parse_result::encoding)
.addProperty("offset",&lxml_parse_result::offset)
.addStaticProperty("status_ok",&lxml_parse_result::status_ok)
.addStaticProperty("status_io_error",&lxml_parse_result::status_io_error)
.addStaticProperty("status_out_of_memory",&lxml_parse_result::status_out_of_memory)
.addStaticProperty("status_internal_error",&lxml_parse_result::status_internal_error)
.addStaticProperty("status_unrecognized_tag",&lxml_parse_result::status_unrecognized_tag)
.addStaticProperty("status_bad_pi",&lxml_parse_result::status_bad_pi)
.addStaticProperty("status_bad_comment",&lxml_parse_result::status_bad_comment)
.addStaticProperty("status_bad_cdata",&lxml_parse_result::status_bad_cdata)
.addStaticProperty("status_bad_doctype",&lxml_parse_result::status_bad_doctype)
.addStaticProperty("status_bad_pcdata",&lxml_parse_result::status_bad_pcdata)
.addStaticProperty("status_bad_start_element",&lxml_parse_result::status_bad_start_element)
.addStaticProperty("status_bad_attribute",&lxml_parse_result::status_bad_attribute)
.addStaticProperty("status_bad_end_element",&lxml_parse_result::status_bad_end_element)
.addStaticProperty("status_end_element_mismatch",&lxml_parse_result::status_end_element_mismatch)
.addStaticProperty("status_file_not_found",&lxml_parse_result::status_file_not_found)
.endClass()
.beginClass<lxml_node>("xml_node")
.addConstructor<void (*)()>()
.addProperty("valid",&lxml_node::valid)
.addProperty("name",&lxml_node::name)
.addProperty("value",&lxml_node::value)
.addProperty("type",&lxml_node::type)
.addProperty("path",&lxml_node::path)
.addProperty("text",&lxml_node::text)
.addFunction("child",&lxml_node::child)
.addFunction("first_attribute",&lxml_node::first_attribute)
.addFunction("last_attribute",&lxml_node::last_attribute)
.addFunction("first_child",&lxml_node::first_child)
.addFunction("last_child",&lxml_node::last_child)
.addFunction("parent",&lxml_node::parent)
.addFunction("root",&lxml_node::root)
.addFunction("attribute",&lxml_node::attribute)
.addFunction("next",&lxml_node::next)
.addFunction("previous",&lxml_node::previous)
.addFunction("next_sibling",&lxml_node::next_sibling)
.addFunction("previous_sibling",&lxml_node::previous_sibling)
.addFunction("child_value",&lxml_node::child_value)
.addFunction("set_name",&lxml_node::set_name)
.addFunction("set_value",&lxml_node::set_value)
.addFunction("append_attribute",&lxml_node::append_attribute)
.addFunction("prepend_attribute",&lxml_node::prepend_attribute)
.addFunction("insert_attribute_after",&lxml_node::insert_attribute_after)
.addFunction("insert_attribute_before",&lxml_node::insert_attribute_before)
.addFunction("append_attribute_copy",&lxml_node::append_attribute_copy)
.addFunction("prepend_attribute_copy",&lxml_node::prepend_attribute_copy)
.addFunction("insert_attribute_copy_after",&lxml_node::insert_attribute_copy_after)
.addFunction("insert_attribute_copy_before",&lxml_node::insert_attribute_copy_before)
.addFunction("append",&lxml_node::append)
.addFunction("prepend",&lxml_node::prepend)
.addFunction("insert_after",&lxml_node::insert_after)
.addFunction("insert_before",&lxml_node::insert_before)
.addFunction("append_child",&lxml_node::append_child)
.addFunction("prepend_child",&lxml_node::prepend_child)
.addFunction("insert_child_after",&lxml_node::insert_child_after)
.addFunction("insert_child_before",&lxml_node::insert_child_before)
.addFunction("append_copy",&lxml_node::append_copy)
.addFunction("prepend_copy",&lxml_node::prepend_copy)
.addFunction("insert_copy_after",&lxml_node::insert_copy_after)
.addFunction("insert_copy_before",&lxml_node::insert_copy_before)
.addFunction("remove_attribute",&lxml_node::remove_attribute)
.addFunction("remove_attribute_by_name",&lxml_node::remove_attribute_by_name)
.addFunction("remove_child",&lxml_node::remove_child)
.addFunction("remove_child_by_name",&lxml_node::remove_child_by_name)
.addFunction("find_child_by_name_and_attribute",&lxml_node::find_child_by_name_and_attribute)
.addFunction("find_child_by_attribute",&lxml_node::find_child_by_attribute)
.addFunction("first_element_by_path",&lxml_node::first_element_by_path)
.addFunction("select_single_node",&lxml_node::select_single_node)
.addFunction("select_nodes",&lxml_node::select_nodes)
.endClass()
.beginClass<lxml_document>("xml_document")
.addConstructor<void (*)()>()
.addProperty("valid",&lxml_document::valid)
.addFunction("root",&lxml_document::root)
.addFunction("reset",&lxml_document::reset)
.addFunction("load_file",&lxml_document::load_file)
.addFunction("child",&lxml_document::child)
.addFunction("load",&lxml_document::load)
.addFunction("save_file",&lxml_document::save_file)
.endClass()
.beginClass<lxpath_node>("xpath_node")
.addConstructor<void (*)()>()
.addProperty("valid",&lxpath_node::valid)
.addFunction("node",&lxpath_node::node)
.addFunction("attribute",&lxpath_node::attribute)
.endClass()
.beginClass<lxpath_node_set>("xpath_node_set")
.addConstructor<void (*)()>()
.addProperty("type",&lxpath_node_set::type)
.addProperty("size",&lxpath_node_set::size)
.addStaticProperty("type_unsorted",&lxpath_node_set::type_unsorted)
.addStaticProperty("type_sorted",&lxpath_node_set::type_sorted)
.addStaticProperty("type_sorted_reverse",&lxpath_node_set::type_sorted_reverse)
.addFunction("get",&lxpath_node_set::get)
.addFunction("sort",&lxpath_node_set::sort)
.endClass()
.endNamespace()

View File

@ -1,27 +1,27 @@
#include "pugixml.hpp"
#include <iostream>
int main()
{
//[code_save_declaration
// get a test document
pugi::xml_document doc;
doc.load("<foo bar='baz'><call>hey</call></foo>");
// add a custom declaration node
pugi::xml_node decl = doc.prepend_child(pugi::node_declaration);
decl.append_attribute("version") = "1.0";
decl.append_attribute("encoding") = "UTF-8";
decl.append_attribute("standalone") = "no";
// <?xml version="1.0" encoding="UTF-8" standalone="no"?>
// <foo bar="baz">
// <call>hey</call>
// </foo>
doc.save(std::cout);
std::cout << std::endl;
//]
}
// vim:et
#include "pugixml.hpp"
#include <iostream>
int main()
{
//[code_save_declaration
// get a test document
pugi::xml_document doc;
doc.load("<foo bar='baz'><call>hey</call></foo>");
// add a custom declaration node
pugi::xml_node decl = doc.prepend_child(pugi::node_declaration);
decl.append_attribute("version") = "1.0";
decl.append_attribute("encoding") = "UTF-8";
decl.append_attribute("standalone") = "no";
// <?xml version="1.0" encoding="UTF-8" standalone="no"?>
// <foo bar="baz">
// <call>hey</call>
// </foo>
doc.save(std::cout);
std::cout << std::endl;
//]
}
// vim:et

View File

@ -1,35 +1,35 @@
#include "pugixml.hpp"
#include <iostream>
int main()
{
pugi::xml_document doc;
// get a test document
doc.load("<project><name>test</name><version>1.1</version><public>yes</public></project>");
pugi::xml_node project = doc.child("project");
//[code_text_access
std::cout << "Project name: " << project.child("name").text().get() << std::endl;
std::cout << "Project version: " << project.child("version").text().as_double() << std::endl;
std::cout << "Project visibility: " << (project.child("public").text().as_bool(/* def= */ true) ? "public" : "private") << std::endl;
std::cout << "Project description: " << project.child("description").text().get() << std::endl;
//]
std::cout << std::endl;
//[code_text_modify
// change project version
project.child("version").text() = 1.2;
// add description element and set the contents
// note that we do not have to explicitly add the node_pcdata child
project.append_child("description").text().set("a test project");
//]
doc.save(std::cout);
}
// vim:et
#include "pugixml.hpp"
#include <iostream>
int main()
{
pugi::xml_document doc;
// get a test document
doc.load("<project><name>test</name><version>1.1</version><public>yes</public></project>");
pugi::xml_node project = doc.child("project");
//[code_text_access
std::cout << "Project name: " << project.child("name").text().get() << std::endl;
std::cout << "Project version: " << project.child("version").text().as_double() << std::endl;
std::cout << "Project visibility: " << (project.child("public").text().as_bool(/* def= */ true) ? "public" : "private") << std::endl;
std::cout << "Project description: " << project.child("description").text().get() << std::endl;
//]
std::cout << std::endl;
//[code_text_modify
// change project version
project.child("version").text() = 1.2;
// add description element and set the contents
// note that we do not have to explicitly add the node_pcdata child
project.append_child("description").text().set("a test project");
//]
doc.save(std::cout);
}
// vim:et

View File

@ -1,32 +1,32 @@
#include "pugixml.hpp"
#include <iostream>
int main()
{
pugi::xml_document doc;
if (!doc.load_file("xgconsole.xml")) return -1;
pugi::xml_node tools = doc.child("Profile").child("Tools");
//[code_traverse_rangefor
for (pugi::xml_node tool: tools.children("Tool"))
{
std::cout << "Tool:";
for (pugi::xml_attribute attr: tool.attributes())
{
std::cout << " " << attr.name() << "=" << attr.value();
}
for (pugi::xml_node child: tool.children())
{
std::cout << ", child " << child.name();
}
std::cout << std::endl;
}
//]
}
// vim:et
#include "pugixml.hpp"
#include <iostream>
int main()
{
pugi::xml_document doc;
if (!doc.load_file("xgconsole.xml")) return -1;
pugi::xml_node tools = doc.child("Profile").child("Tools");
//[code_traverse_rangefor
for (pugi::xml_node tool: tools.children("Tool"))
{
std::cout << "Tool:";
for (pugi::xml_attribute attr: tool.attributes())
{
std::cout << " " << attr.name() << "=" << attr.value();
}
for (pugi::xml_node child: tool.children())
{
std::cout << ", child " << child.name();
}
std::cout << std::endl;
}
//]
}
// vim:et

View File

@ -1,38 +1,38 @@
#include "pugixml.hpp"
#include <iostream>
#include <string>
int main()
{
pugi::xml_document doc;
if (!doc.load_file("xgconsole.xml")) return -1;
//[code_xpath_variables
// Select nodes via compiled query
pugi::xpath_variable_set vars;
vars.add("remote", pugi::xpath_type_boolean);
pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
vars.set("remote", true);
pugi::xpath_node_set tools_remote = query_remote_tools.evaluate_node_set(doc);
vars.set("remote", false);
pugi::xpath_node_set tools_local = query_remote_tools.evaluate_node_set(doc);
std::cout << "Remote tool: ";
tools_remote[2].node().print(std::cout);
std::cout << "Local tool: ";
tools_local[0].node().print(std::cout);
// You can pass the context directly to select_nodes/select_single_node
pugi::xpath_node_set tools_local_imm = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
std::cout << "Local tool imm: ";
tools_local_imm[0].node().print(std::cout);
//]
}
// vim:et
#include "pugixml.hpp"
#include <iostream>
#include <string>
int main()
{
pugi::xml_document doc;
if (!doc.load_file("xgconsole.xml")) return -1;
//[code_xpath_variables
// Select nodes via compiled query
pugi::xpath_variable_set vars;
vars.add("remote", pugi::xpath_type_boolean);
pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
vars.set("remote", true);
pugi::xpath_node_set tools_remote = query_remote_tools.evaluate_node_set(doc);
vars.set("remote", false);
pugi::xpath_node_set tools_local = query_remote_tools.evaluate_node_set(doc);
std::cout << "Remote tool: ";
tools_remote[2].node().print(std::cout);
std::cout << "Local tool: ";
tools_local[0].node().print(std::cout);
// You can pass the context directly to select_nodes/select_single_node
pugi::xpath_node_set tools_local_imm = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
std::cout << "Local tool imm: ";
tools_local_imm[0].node().print(std::cout);
//]
}
// vim:et

View File

@ -15,15 +15,15 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\pugilua\pugilua.cpp">
<ClCompile Include="..\..\contrib\pugilua\pugilua.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pugilua\pugilua_lib.cpp">
<ClCompile Include="..\..\contrib\pugilua\pugilua_lib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\pugilua\pugilua_lib.h">
<ClInclude Include="..\..\contrib\pugilua\pugilua_lib.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@ -1,13 +1,13 @@
includepaths
{
"../src"
}
files
{
("../src")
pugiconfig.hpp
pugixml.cpp
pugixml.hpp
}
includepaths
{
"../src"
}
files
{
("../src")
pugiconfig.hpp
pugixml.cpp
pugixml.hpp
}

View File

@ -1,19 +1,19 @@
<?xml version="1.0"?>
<!DOCTYPE é_+å + SYSTEM "weekly-utf-8.dtd">
<!-- é_+å +ã'÷ã__ã_-ã_< -->
<mesh name="mesh_root">
<!-- here is a mesh node -->
some text
<![CDATA[someothertext]]>
some more text
<node attr1="value1" attr2="value2" />
<node attr1="value2">
+%è¯- å__å--="name" ä>·å__="value">ä¸-ç_æ_%å__å¤_è¯-è¨_ð¤-¢</æ+%è¯->
<innernode/>
</node>
°_å__>
°_>å++ç"°</æ°_>
<å__>太é__</å__>
</æ°_å__>
<?include somedata?>
</mesh>
<?xml version="1.0"?>
<!DOCTYPE é_+å + SYSTEM "weekly-utf-8.dtd">
<!-- é_+å +ã'÷ã__ã_-ã_< -->
<mesh name="mesh_root">
<!-- here is a mesh node -->
some text
<![CDATA[someothertext]]>
some more text
<node attr1="value1" attr2="value2" />
<node attr1="value2">
+%è¯- å__å--="name" ä>·å__="value">ä¸-ç_æ_%å__å¤_è¯-è¨_ð¤-¢</æ+%è¯->
<innernode/>
</node>
°_å__>
°_>å++ç"°</æ°_>
<å__>太é__</å__>
</æ°_å__>
<?include somedata?>
</mesh>

View File

@ -1,252 +1,252 @@
#include "common.hpp"
#include "helpers.hpp"
TEST_XML_FLAGS(dom_text_empty, "<node><a>foo</a><b><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK(node.child(STR("a")).text());
CHECK(node.child(STR("b")).text());
CHECK(!node.child(STR("c")).text());
CHECK(!node.child(STR("d")).text());
CHECK(!xml_node().text());
CHECK(!xml_text());
generic_empty_test(node.child(STR("a")).text());
}
TEST_XML(dom_text_bool_ops, "<node>foo</node>")
{
generic_bool_ops_test(doc.child(STR("node")).text());
}
TEST_XML_FLAGS(dom_text_get, "<node><a>foo</a><b><node/><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK_STRING(node.child(STR("a")).text().get(), STR("foo"));
CHECK_STRING(node.child(STR("a")).first_child().text().get(), STR("foo"));
CHECK_STRING(node.child(STR("b")).text().get(), STR("bar"));
CHECK_STRING(node.child(STR("b")).last_child().text().get(), STR("bar"));
CHECK_STRING(node.child(STR("c")).text().get(), STR(""));
CHECK_STRING(node.child(STR("c")).first_child().text().get(), STR(""));
CHECK_STRING(node.child(STR("d")).text().get(), STR(""));
CHECK_STRING(xml_node().text().get(), STR(""));
}
TEST_XML_FLAGS(dom_text_as_string, "<node><a>foo</a><b><node/><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK_STRING(node.child(STR("a")).text().as_string(), STR("foo"));
CHECK_STRING(node.child(STR("a")).first_child().text().as_string(), STR("foo"));
CHECK_STRING(node.child(STR("b")).text().as_string(), STR("bar"));
CHECK_STRING(node.child(STR("b")).last_child().text().as_string(), STR("bar"));
CHECK_STRING(node.child(STR("c")).text().as_string(), STR(""));
CHECK_STRING(node.child(STR("c")).first_child().text().as_string(), STR(""));
CHECK_STRING(node.child(STR("d")).text().as_string(), STR(""));
CHECK_STRING(xml_node().text().as_string(), STR(""));
}
TEST_XML(dom_text_as_int, "<node><text1>1</text1><text2>-1</text2><text3>-2147483648</text3><text4>2147483647</text4></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_int() == 0);
CHECK(node.child(STR("text1")).text().as_int() == 1);
CHECK(node.child(STR("text2")).text().as_int() == -1);
CHECK(node.child(STR("text3")).text().as_int() == -2147483647 - 1);
CHECK(node.child(STR("text4")).text().as_int() == 2147483647);
}
TEST_XML(dom_text_as_uint, "<node><text1>0</text1><text2>1</text2><text3>2147483647</text3><text4>4294967295</text4></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_uint() == 0);
CHECK(node.child(STR("text1")).text().as_uint() == 0);
CHECK(node.child(STR("text2")).text().as_uint() == 1);
CHECK(node.child(STR("text3")).text().as_uint() == 2147483647);
CHECK(node.child(STR("text4")).text().as_uint() == 4294967295u);
}
TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_float() == 0);
CHECK_DOUBLE(node.child(STR("text1")).text().as_float(), 0);
CHECK_DOUBLE(node.child(STR("text2")).text().as_float(), 1);
CHECK_DOUBLE(node.child(STR("text3")).text().as_float(), 0.12);
CHECK_DOUBLE(node.child(STR("text4")).text().as_float(), -5.1);
CHECK_DOUBLE(node.child(STR("text5")).text().as_float(), 3e-4);
CHECK_DOUBLE(node.child(STR("text6")).text().as_float(), 3.14159265358979323846);
}
TEST_XML(dom_text_as_double, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_double() == 0);
CHECK_DOUBLE(node.child(STR("text1")).text().as_double(), 0);
CHECK_DOUBLE(node.child(STR("text2")).text().as_double(), 1);
CHECK_DOUBLE(node.child(STR("text3")).text().as_double(), 0.12);
CHECK_DOUBLE(node.child(STR("text4")).text().as_double(), -5.1);
CHECK_DOUBLE(node.child(STR("text5")).text().as_double(), 3e-4);
CHECK_DOUBLE(node.child(STR("text6")).text().as_double(), 3.14159265358979323846);
}
TEST_XML(dom_text_as_bool, "<node><text1>0</text1><text2>1</text2><text3>true</text3><text4>True</text4><text5>Yes</text5><text6>yes</text6><text7>false</text7></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(!xml_text().as_bool());
CHECK(!node.child(STR("text1")).text().as_bool());
CHECK(node.child(STR("text2")).text().as_bool());
CHECK(node.child(STR("text3")).text().as_bool());
CHECK(node.child(STR("text4")).text().as_bool());
CHECK(node.child(STR("text5")).text().as_bool());
CHECK(node.child(STR("text6")).text().as_bool());
CHECK(!node.child(STR("text7")).text().as_bool());
}
TEST_XML(dom_text_get_no_state, "<node/>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
CHECK(!t);
CHECK(t.get() && *t.get() == 0);
CHECK(!node.first_child());
node.append_child(node_pcdata);
CHECK(t);
CHECK_STRING(t.get(), STR(""));
node.first_child().set_value(STR("test"));
CHECK(t);
CHECK_STRING(t.get(), STR("test"));
}
TEST_XML(dom_text_set, "<node/>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
t.set(STR(""));
CHECK(node.first_child().type() == node_pcdata);
CHECK_NODE(node, STR("<node></node>"));
t.set(STR("boo"));
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>boo</node>"));
t.set(STR("foobarfoobar"));
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
}
TEST_XML(dom_text_assign, "<node/>")
{
xml_node node = doc.child(STR("node"));
node.append_child(STR("text1")).text() = STR("v1");
xml_text() = STR("v1");
node.append_child(STR("text2")).text() = -2147483647;
node.append_child(STR("text3")).text() = -2147483647 - 1;
xml_text() = -2147483647 - 1;
node.append_child(STR("text4")).text() = 4294967295u;
node.append_child(STR("text5")).text() = 4294967294u;
xml_text() = 2147483647;
node.append_child(STR("text6")).text() = 0.5;
xml_text() = 0.5;
node.append_child(STR("text7")).text() = true;
xml_text() = true;
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
}
TEST_XML(dom_text_set_value, "<node/>")
{
xml_node node = doc.child(STR("node"));
CHECK(node.append_child(STR("text1")).text().set(STR("v1")));
CHECK(!xml_text().set(STR("v1")));
CHECK(node.append_child(STR("text2")).text().set(-2147483647));
CHECK(node.append_child(STR("text3")).text().set(-2147483647 - 1));
CHECK(!xml_text().set(-2147483647 - 1));
CHECK(node.append_child(STR("text4")).text().set(4294967295u));
CHECK(node.append_child(STR("text5")).text().set(4294967294u));
CHECK(!xml_text().set(2147483647));
CHECK(node.append_child(STR("text6")).text().set(0.5));
CHECK(!xml_text().set(0.5));
CHECK(node.append_child(STR("text7")).text().set(true));
CHECK(!xml_text().set(true));
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
}
TEST_XML(dom_text_middle, "<node><c1>notthisone</c1>text<c2/></node>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
CHECK_STRING(t.get(), STR("text"));
t.set(STR("notext"));
CHECK_NODE(node, STR("<node><c1>notthisone</c1>notext<c2 /></node>"));
CHECK(node.remove_child(t.data()));
CHECK(!t);
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2 /></node>"));
t.set(STR("yestext"));
CHECK(t);
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2 />yestext</node>"));
CHECK(t.data() == node.last_child());
}
TEST_XML_FLAGS(dom_text_data, "<node><a>foo</a><b><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK(node.child(STR("a")).text().data() == node.child(STR("a")).first_child());
CHECK(node.child(STR("b")).text().data() == node.child(STR("b")).first_child());
CHECK(!node.child(STR("c")).text().data());
CHECK(!node.child(STR("d")).text().data());
CHECK(!xml_text().data());
}
TEST(dom_text_defaults)
{
xml_text text;
CHECK_STRING(text.as_string(STR("foo")), STR("foo"));
CHECK(text.as_int(42) == 42);
CHECK(text.as_uint(42) == 42);
CHECK(text.as_double(42) == 42);
CHECK(text.as_float(42) == 42);
CHECK(text.as_bool(true) == true);
}
#include "common.hpp"
#include "helpers.hpp"
TEST_XML_FLAGS(dom_text_empty, "<node><a>foo</a><b><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK(node.child(STR("a")).text());
CHECK(node.child(STR("b")).text());
CHECK(!node.child(STR("c")).text());
CHECK(!node.child(STR("d")).text());
CHECK(!xml_node().text());
CHECK(!xml_text());
generic_empty_test(node.child(STR("a")).text());
}
TEST_XML(dom_text_bool_ops, "<node>foo</node>")
{
generic_bool_ops_test(doc.child(STR("node")).text());
}
TEST_XML_FLAGS(dom_text_get, "<node><a>foo</a><b><node/><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK_STRING(node.child(STR("a")).text().get(), STR("foo"));
CHECK_STRING(node.child(STR("a")).first_child().text().get(), STR("foo"));
CHECK_STRING(node.child(STR("b")).text().get(), STR("bar"));
CHECK_STRING(node.child(STR("b")).last_child().text().get(), STR("bar"));
CHECK_STRING(node.child(STR("c")).text().get(), STR(""));
CHECK_STRING(node.child(STR("c")).first_child().text().get(), STR(""));
CHECK_STRING(node.child(STR("d")).text().get(), STR(""));
CHECK_STRING(xml_node().text().get(), STR(""));
}
TEST_XML_FLAGS(dom_text_as_string, "<node><a>foo</a><b><node/><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK_STRING(node.child(STR("a")).text().as_string(), STR("foo"));
CHECK_STRING(node.child(STR("a")).first_child().text().as_string(), STR("foo"));
CHECK_STRING(node.child(STR("b")).text().as_string(), STR("bar"));
CHECK_STRING(node.child(STR("b")).last_child().text().as_string(), STR("bar"));
CHECK_STRING(node.child(STR("c")).text().as_string(), STR(""));
CHECK_STRING(node.child(STR("c")).first_child().text().as_string(), STR(""));
CHECK_STRING(node.child(STR("d")).text().as_string(), STR(""));
CHECK_STRING(xml_node().text().as_string(), STR(""));
}
TEST_XML(dom_text_as_int, "<node><text1>1</text1><text2>-1</text2><text3>-2147483648</text3><text4>2147483647</text4></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_int() == 0);
CHECK(node.child(STR("text1")).text().as_int() == 1);
CHECK(node.child(STR("text2")).text().as_int() == -1);
CHECK(node.child(STR("text3")).text().as_int() == -2147483647 - 1);
CHECK(node.child(STR("text4")).text().as_int() == 2147483647);
}
TEST_XML(dom_text_as_uint, "<node><text1>0</text1><text2>1</text2><text3>2147483647</text3><text4>4294967295</text4></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_uint() == 0);
CHECK(node.child(STR("text1")).text().as_uint() == 0);
CHECK(node.child(STR("text2")).text().as_uint() == 1);
CHECK(node.child(STR("text3")).text().as_uint() == 2147483647);
CHECK(node.child(STR("text4")).text().as_uint() == 4294967295u);
}
TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_float() == 0);
CHECK_DOUBLE(node.child(STR("text1")).text().as_float(), 0);
CHECK_DOUBLE(node.child(STR("text2")).text().as_float(), 1);
CHECK_DOUBLE(node.child(STR("text3")).text().as_float(), 0.12);
CHECK_DOUBLE(node.child(STR("text4")).text().as_float(), -5.1);
CHECK_DOUBLE(node.child(STR("text5")).text().as_float(), 3e-4);
CHECK_DOUBLE(node.child(STR("text6")).text().as_float(), 3.14159265358979323846);
}
TEST_XML(dom_text_as_double, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_double() == 0);
CHECK_DOUBLE(node.child(STR("text1")).text().as_double(), 0);
CHECK_DOUBLE(node.child(STR("text2")).text().as_double(), 1);
CHECK_DOUBLE(node.child(STR("text3")).text().as_double(), 0.12);
CHECK_DOUBLE(node.child(STR("text4")).text().as_double(), -5.1);
CHECK_DOUBLE(node.child(STR("text5")).text().as_double(), 3e-4);
CHECK_DOUBLE(node.child(STR("text6")).text().as_double(), 3.14159265358979323846);
}
TEST_XML(dom_text_as_bool, "<node><text1>0</text1><text2>1</text2><text3>true</text3><text4>True</text4><text5>Yes</text5><text6>yes</text6><text7>false</text7></node>")
{
xml_node node = doc.child(STR("node"));
CHECK(!xml_text().as_bool());
CHECK(!node.child(STR("text1")).text().as_bool());
CHECK(node.child(STR("text2")).text().as_bool());
CHECK(node.child(STR("text3")).text().as_bool());
CHECK(node.child(STR("text4")).text().as_bool());
CHECK(node.child(STR("text5")).text().as_bool());
CHECK(node.child(STR("text6")).text().as_bool());
CHECK(!node.child(STR("text7")).text().as_bool());
}
TEST_XML(dom_text_get_no_state, "<node/>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
CHECK(!t);
CHECK(t.get() && *t.get() == 0);
CHECK(!node.first_child());
node.append_child(node_pcdata);
CHECK(t);
CHECK_STRING(t.get(), STR(""));
node.first_child().set_value(STR("test"));
CHECK(t);
CHECK_STRING(t.get(), STR("test"));
}
TEST_XML(dom_text_set, "<node/>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
t.set(STR(""));
CHECK(node.first_child().type() == node_pcdata);
CHECK_NODE(node, STR("<node></node>"));
t.set(STR("boo"));
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>boo</node>"));
t.set(STR("foobarfoobar"));
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
}
TEST_XML(dom_text_assign, "<node/>")
{
xml_node node = doc.child(STR("node"));
node.append_child(STR("text1")).text() = STR("v1");
xml_text() = STR("v1");
node.append_child(STR("text2")).text() = -2147483647;
node.append_child(STR("text3")).text() = -2147483647 - 1;
xml_text() = -2147483647 - 1;
node.append_child(STR("text4")).text() = 4294967295u;
node.append_child(STR("text5")).text() = 4294967294u;
xml_text() = 2147483647;
node.append_child(STR("text6")).text() = 0.5;
xml_text() = 0.5;
node.append_child(STR("text7")).text() = true;
xml_text() = true;
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
}
TEST_XML(dom_text_set_value, "<node/>")
{
xml_node node = doc.child(STR("node"));
CHECK(node.append_child(STR("text1")).text().set(STR("v1")));
CHECK(!xml_text().set(STR("v1")));
CHECK(node.append_child(STR("text2")).text().set(-2147483647));
CHECK(node.append_child(STR("text3")).text().set(-2147483647 - 1));
CHECK(!xml_text().set(-2147483647 - 1));
CHECK(node.append_child(STR("text4")).text().set(4294967295u));
CHECK(node.append_child(STR("text5")).text().set(4294967294u));
CHECK(!xml_text().set(2147483647));
CHECK(node.append_child(STR("text6")).text().set(0.5));
CHECK(!xml_text().set(0.5));
CHECK(node.append_child(STR("text7")).text().set(true));
CHECK(!xml_text().set(true));
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
}
TEST_XML(dom_text_middle, "<node><c1>notthisone</c1>text<c2/></node>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
CHECK_STRING(t.get(), STR("text"));
t.set(STR("notext"));
CHECK_NODE(node, STR("<node><c1>notthisone</c1>notext<c2 /></node>"));
CHECK(node.remove_child(t.data()));
CHECK(!t);
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2 /></node>"));
t.set(STR("yestext"));
CHECK(t);
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2 />yestext</node>"));
CHECK(t.data() == node.last_child());
}
TEST_XML_FLAGS(dom_text_data, "<node><a>foo</a><b><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
CHECK(node.child(STR("a")).text().data() == node.child(STR("a")).first_child());
CHECK(node.child(STR("b")).text().data() == node.child(STR("b")).first_child());
CHECK(!node.child(STR("c")).text().data());
CHECK(!node.child(STR("d")).text().data());
CHECK(!xml_text().data());
}
TEST(dom_text_defaults)
{
xml_text text;
CHECK_STRING(text.as_string(STR("foo")), STR("foo"));
CHECK(text.as_int(42) == 42);
CHECK(text.as_uint(42) == 42);
CHECK(text.as_double(42) == 42);
CHECK(text.as_float(42) == 42);
CHECK(text.as_bool(true) == true);
}

View File

@ -1,5 +1,5 @@
// Tests compatibility with string/iostream
#include <string>
#include "../src/pugixml.hpp"
#include <istream>
#include <ostream>
// Tests compatibility with string/iostream
#include <string>
#include "../src/pugixml.hpp"
#include <istream>
#include <ostream>

View File

@ -1,5 +1,5 @@
#include "../src/pugixml.hpp"
#if PUGIXML_VERSION != 120
#error Unexpected pugixml version
#endif
#include "../src/pugixml.hpp"
#if PUGIXML_VERSION != 120
#error Unexpected pugixml version
#endif

View File

@ -1,402 +1,402 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include <string>
TEST(xpath_variables_type_none)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_none);
CHECK(!var);
}
TEST(xpath_variables_type_boolean)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_boolean);
CHECK(var);
CHECK(var->type() == xpath_type_boolean);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(var->set(true));
CHECK(!var->set(1.0));
CHECK(!var->set(STR("abc")));
CHECK(!var->set(xpath_node_set()));
CHECK(var->get_boolean() == true);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
}
TEST(xpath_variables_type_number)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_number);
CHECK(var);
CHECK(var->type() == xpath_type_number);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE(var->get_number(), 0);
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(!var->set(true));
CHECK(var->set(1.0));
CHECK(!var->set(STR("abc")));
CHECK(!var->set(xpath_node_set()));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE(var->get_number(), 1);
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
}
TEST(xpath_variables_type_string)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_string);
CHECK(var);
CHECK(var->type() == xpath_type_string);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(!var->set(true));
CHECK(!var->set(1.0));
CHECK(var->set(STR("abc")));
CHECK(!var->set(xpath_node_set()));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR("abc"));
CHECK(var->get_node_set().empty());
}
TEST_XML(xpath_variables_type_node_set, "<node/>")
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_node_set);
CHECK(var);
CHECK(var->type() == xpath_type_node_set);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(!var->set(true));
CHECK(!var->set(1.0));
CHECK(!var->set(STR("abc")));
CHECK(var->set(doc.select_nodes(STR("*"))));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().size() == 1 && var->get_node_set()[0] == doc.first_child());
}
TEST(xpath_variables_set_operations)
{
xpath_variable_set set;
xpath_variable* v1 = set.add(STR("var1"), xpath_type_number);
CHECK(v1);
xpath_variable* v2 = set.add(STR("var2"), xpath_type_string);
CHECK(v2);
CHECK(v1 != v2);
CHECK(set.add(STR("var1"), xpath_type_number) == v1);
CHECK(set.add(STR("var2"), xpath_type_string) == v2);
CHECK(set.add(STR("var2"), xpath_type_node_set) == 0);
CHECK(set.get(STR("var1")) == v1);
CHECK(set.get(STR("var2")) == v2);
CHECK(set.get(STR("var")) == 0);
CHECK(set.get(STR("var11")) == 0);
CHECK(static_cast<const xpath_variable_set&>(set).get(STR("var1")) == v1);
CHECK(static_cast<const xpath_variable_set&>(set).get(STR("var3")) == 0);
}
TEST_XML(xpath_variables_set_operations_set, "<node/>")
{
xpath_variable_set set;
xpath_variable* v1 = set.add(STR("var1"), xpath_type_number);
CHECK(v1);
xpath_variable* v2 = set.add(STR("var2"), xpath_type_string);
CHECK(v2);
CHECK(set.set(STR("var1"), 1.0));
CHECK_DOUBLE(v1->get_number(), 1.0);
CHECK(set.set(STR("var2"), STR("value")));
CHECK_STRING(v2->get_string(), STR("value"));
CHECK(!set.set(STR("var1"), true));
CHECK(set.set(STR("var3"), doc.select_nodes(STR("*"))));
xpath_variable* v3 = set.get(STR("var3"));
CHECK(v3);
CHECK(v3->type() == xpath_type_node_set);
CHECK(v3->get_node_set().size() == 1);
}
TEST(xpath_variables_set_out_of_memory)
{
test_runner::_memory_fail_threshold = 1;
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_number);
CHECK(!var);
}
TEST(xpath_variables_out_of_memory)
{
test_runner::_memory_fail_threshold = 64;
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_string);
CHECK(var);
CHECK(!var->set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")));
}
TEST_XML(xpath_variables_evaluate, "<node/>")
{
xpath_variable_set set;
set.set(STR("var1"), true);
set.set(STR("var2"), 0.5);
set.set(STR("var3"), STR("value"));
set.set(STR("var4"), doc.select_nodes(STR("*")));
CHECK_XPATH_BOOLEAN_VAR(doc, STR("$var1"), &set, true);
CHECK_XPATH_NUMBER_VAR(doc, STR("$var2"), &set, 0.5);
CHECK_XPATH_STRING_VAR(doc, STR("$var3"), &set, STR("value"));
CHECK_XPATH_NODESET_VAR(doc, STR("$var4"), &set) % 2;
}
TEST_XML(xpath_variables_evaluate_conversion, "<node>3</node>")
{
xpath_variable_set set;
set.set(STR("var"), doc.select_nodes(STR("*")));
CHECK_XPATH_BOOLEAN_VAR(doc, STR("$var"), &set, true);
CHECK_XPATH_NUMBER_VAR(doc, STR("$var"), &set, 3);
CHECK_XPATH_STRING_VAR(doc, STR("$var"), &set, STR("3"));
CHECK_XPATH_NODESET_VAR(doc, STR("$var"), &set) % 2;
}
TEST(xpath_variables_evaluate_node_set_fail)
{
xpath_variable_set set;
set.set(STR("var"), false);
xpath_query q(STR("$var"), &set);
#ifdef PUGIXML_NO_EXCEPTIONS
CHECK(q.evaluate_node_set(xml_node()).empty());
#else
try
{
q.evaluate_node_set(xml_node());
CHECK_FORCE_FAIL("Expected exception");
}
catch (const xpath_exception&)
{
}
#endif
}
TEST(xpath_variables_multiple_documents)
{
xml_document doc;
doc.append_child().set_name(STR("node"));
xml_document doc1;
doc1.append_child().set_name(STR("node"));
xml_document doc2;
doc2.append_child().set_name(STR("node"));
xpath_variable_set set;
set.set(STR("var1"), doc1.select_nodes(STR("*")));
set.set(STR("var2"), doc2.select_nodes(STR("*")));
xpath_node_set ns = doc.select_nodes(STR("$var1 | $var2 | node"), &set);
ns.sort();
CHECK(ns.size() == 3);
CHECK(ns[0] != ns[1] && ns[0] != ns[2]);
xml_node n0 = doc.child(STR("node")), n1 = doc1.child(STR("node")), n2 = doc2.child(STR("node"));
CHECK(n0 == ns[0].node() || n0 == ns[1].node() || n0 == ns[2].node());
CHECK(n1 == ns[0].node() || n1 == ns[1].node() || n1 == ns[2].node());
CHECK(n2 == ns[0].node() || n2 == ns[1].node() || n2 == ns[2].node());
}
TEST(xpath_variables_long_name)
{
xpath_variable_set set;
set.set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &set, true);
}
TEST_XML(xpath_variables_select, "<node attr='1'/><node attr='2'/>")
{
xpath_variable_set set;
set.set(STR("one"), 1.0);
xpath_node_set ns = doc.select_nodes(STR("node[@attr=$one+1]"), &set);
CHECK(ns.size() == 1 && ns[0].node() == doc.last_child());
xpath_node n = doc.select_single_node(STR("node[@attr=$one+1]"), &set);
CHECK(n == ns[0]);
}
TEST(xpath_variables_empty_name)
{
xpath_variable_set set;
CHECK(!set.add(STR(""), xpath_type_number));
}
TEST_XML(xpath_variables_inside_filter, "<node key='1' value='2'/><node key='2' value='1'/><node key='1' value='1'/>")
{
xpath_variable_set set;
set.set(STR("one"), 1.0);
xpath_node_set ns = doc.select_nodes(STR("(node[@key = $one])[@value = $one]"), &set);
CHECK(ns.size() == 1 && ns[0].node() == doc.last_child());
}
TEST_XML(xpath_variables_step, "<node><child/><child/><child><child/></child></node>")
{
xpath_variable_set set;
set.set(STR("root"), doc.select_nodes(STR("node")));
CHECK_XPATH_NODESET_VAR(xml_node(), STR("$root/child"), &set) % 3 % 4 % 5;
CHECK_XPATH_NODESET_VAR(xml_node(), STR("$root//child"), &set) % 3 % 4 % 5 % 6;
}
TEST_XML(xpath_variables_index, "<node><child/><child/><child><child/></child></node>")
{
xpath_variable_set set;
set.set(STR("index"), 2.0);
CHECK_XPATH_NODESET_VAR(doc, STR("node/child[$index]"), &set) % 4;
CHECK_XPATH_NODESET_VAR(doc, STR("node/child[position()=$index]"), &set) % 4;
}
TEST(xpath_variables_qname)
{
xpath_variable_set set;
set.set(STR("foo:bar"), true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$foo:bar"), &set, true);
}
TEST(xpath_variables_name_error)
{
xpath_variable_set set;
set.set(STR("foo:"), true);
set.set(STR(":bar"), true);
set.set(STR("foo:*"), true);
set.set(STR("foo"), true);
set.set(STR("3"), true);
CHECK_XPATH_FAIL_VAR(STR("$foo:"), &set);
CHECK_XPATH_FAIL_VAR(STR("$:bar"), &set);
CHECK_XPATH_FAIL_VAR(STR("$foo:*"), &set);
CHECK_XPATH_FAIL_VAR(STR("$foo:bar:baz"), &set);
CHECK_XPATH_FAIL_VAR(STR("$ foo"), &set);
CHECK_XPATH_FAIL_VAR(STR("$3"), &set);
}
TEST(xpath_variables_empty_string)
{
xpath_variable_set set;
set.add(STR("empty"), xpath_type_string);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$empty = substring-before('a', 'z')"), &set, true);
}
TEST(xpath_variables_name_underscore)
{
xpath_variable_set set;
set.set(STR("_foo_bar"), true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$_foo_bar"), &set, true);
}
TEST(xpath_variables_name_case)
{
xpath_variable_set set;
set.set(STR("i"), 5.0);
set.set(STR("I"), 2.0);
CHECK_XPATH_NUMBER_VAR(xml_node(), STR("$i div $I"), &set, 2.5);
}
TEST(xpath_variables_name_unicode)
{
#ifdef PUGIXML_WCHAR_MODE
#ifdef U_LITERALS
const char_t* name = L"\u0400\u203D";
#else
const char_t* name = L"\x0400\x203D";
#endif
#else
const char_t* name = "\xd0\x80\xe2\x80\xbd";
#endif
xpath_variable_set set;
set.set(name, STR("value"));
std::basic_string<char_t> var = STR("$");
var += name;
CHECK_XPATH_STRING_VAR(xml_node(), var.c_str(), &set, STR("value"));
}
TEST_XML(xpath_variables_count_sum, "<node><c1>12</c1><c2>23</c2><c3>34</c3></node>")
{
xpath_variable_set set;
set.set(STR("c12"), doc.select_nodes(STR("node/c1 | node/c2")));
set.set(STR("c3"), doc.select_nodes(STR("node/c3")));
set.set(STR("c"), doc.select_nodes(STR("node/*")));
CHECK_XPATH_NUMBER_VAR(xml_node(), STR("sum($c12) * count($c) - sum($c3)"), &set, 71);
}
#endif
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include <string>
TEST(xpath_variables_type_none)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_none);
CHECK(!var);
}
TEST(xpath_variables_type_boolean)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_boolean);
CHECK(var);
CHECK(var->type() == xpath_type_boolean);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(var->set(true));
CHECK(!var->set(1.0));
CHECK(!var->set(STR("abc")));
CHECK(!var->set(xpath_node_set()));
CHECK(var->get_boolean() == true);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
}
TEST(xpath_variables_type_number)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_number);
CHECK(var);
CHECK(var->type() == xpath_type_number);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE(var->get_number(), 0);
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(!var->set(true));
CHECK(var->set(1.0));
CHECK(!var->set(STR("abc")));
CHECK(!var->set(xpath_node_set()));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE(var->get_number(), 1);
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
}
TEST(xpath_variables_type_string)
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_string);
CHECK(var);
CHECK(var->type() == xpath_type_string);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(!var->set(true));
CHECK(!var->set(1.0));
CHECK(var->set(STR("abc")));
CHECK(!var->set(xpath_node_set()));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR("abc"));
CHECK(var->get_node_set().empty());
}
TEST_XML(xpath_variables_type_node_set, "<node/>")
{
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_node_set);
CHECK(var);
CHECK(var->type() == xpath_type_node_set);
CHECK_STRING(var->name(), STR("target"));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().empty());
CHECK(!var->set(true));
CHECK(!var->set(1.0));
CHECK(!var->set(STR("abc")));
CHECK(var->set(doc.select_nodes(STR("*"))));
CHECK(var->get_boolean() == false);
CHECK_DOUBLE_NAN(var->get_number());
CHECK_STRING(var->get_string(), STR(""));
CHECK(var->get_node_set().size() == 1 && var->get_node_set()[0] == doc.first_child());
}
TEST(xpath_variables_set_operations)
{
xpath_variable_set set;
xpath_variable* v1 = set.add(STR("var1"), xpath_type_number);
CHECK(v1);
xpath_variable* v2 = set.add(STR("var2"), xpath_type_string);
CHECK(v2);
CHECK(v1 != v2);
CHECK(set.add(STR("var1"), xpath_type_number) == v1);
CHECK(set.add(STR("var2"), xpath_type_string) == v2);
CHECK(set.add(STR("var2"), xpath_type_node_set) == 0);
CHECK(set.get(STR("var1")) == v1);
CHECK(set.get(STR("var2")) == v2);
CHECK(set.get(STR("var")) == 0);
CHECK(set.get(STR("var11")) == 0);
CHECK(static_cast<const xpath_variable_set&>(set).get(STR("var1")) == v1);
CHECK(static_cast<const xpath_variable_set&>(set).get(STR("var3")) == 0);
}
TEST_XML(xpath_variables_set_operations_set, "<node/>")
{
xpath_variable_set set;
xpath_variable* v1 = set.add(STR("var1"), xpath_type_number);
CHECK(v1);
xpath_variable* v2 = set.add(STR("var2"), xpath_type_string);
CHECK(v2);
CHECK(set.set(STR("var1"), 1.0));
CHECK_DOUBLE(v1->get_number(), 1.0);
CHECK(set.set(STR("var2"), STR("value")));
CHECK_STRING(v2->get_string(), STR("value"));
CHECK(!set.set(STR("var1"), true));
CHECK(set.set(STR("var3"), doc.select_nodes(STR("*"))));
xpath_variable* v3 = set.get(STR("var3"));
CHECK(v3);
CHECK(v3->type() == xpath_type_node_set);
CHECK(v3->get_node_set().size() == 1);
}
TEST(xpath_variables_set_out_of_memory)
{
test_runner::_memory_fail_threshold = 1;
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_number);
CHECK(!var);
}
TEST(xpath_variables_out_of_memory)
{
test_runner::_memory_fail_threshold = 64;
xpath_variable_set set;
xpath_variable* var = set.add(STR("target"), xpath_type_string);
CHECK(var);
CHECK(!var->set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")));
}
TEST_XML(xpath_variables_evaluate, "<node/>")
{
xpath_variable_set set;
set.set(STR("var1"), true);
set.set(STR("var2"), 0.5);
set.set(STR("var3"), STR("value"));
set.set(STR("var4"), doc.select_nodes(STR("*")));
CHECK_XPATH_BOOLEAN_VAR(doc, STR("$var1"), &set, true);
CHECK_XPATH_NUMBER_VAR(doc, STR("$var2"), &set, 0.5);
CHECK_XPATH_STRING_VAR(doc, STR("$var3"), &set, STR("value"));
CHECK_XPATH_NODESET_VAR(doc, STR("$var4"), &set) % 2;
}
TEST_XML(xpath_variables_evaluate_conversion, "<node>3</node>")
{
xpath_variable_set set;
set.set(STR("var"), doc.select_nodes(STR("*")));
CHECK_XPATH_BOOLEAN_VAR(doc, STR("$var"), &set, true);
CHECK_XPATH_NUMBER_VAR(doc, STR("$var"), &set, 3);
CHECK_XPATH_STRING_VAR(doc, STR("$var"), &set, STR("3"));
CHECK_XPATH_NODESET_VAR(doc, STR("$var"), &set) % 2;
}
TEST(xpath_variables_evaluate_node_set_fail)
{
xpath_variable_set set;
set.set(STR("var"), false);
xpath_query q(STR("$var"), &set);
#ifdef PUGIXML_NO_EXCEPTIONS
CHECK(q.evaluate_node_set(xml_node()).empty());
#else
try
{
q.evaluate_node_set(xml_node());
CHECK_FORCE_FAIL("Expected exception");
}
catch (const xpath_exception&)
{
}
#endif
}
TEST(xpath_variables_multiple_documents)
{
xml_document doc;
doc.append_child().set_name(STR("node"));
xml_document doc1;
doc1.append_child().set_name(STR("node"));
xml_document doc2;
doc2.append_child().set_name(STR("node"));
xpath_variable_set set;
set.set(STR("var1"), doc1.select_nodes(STR("*")));
set.set(STR("var2"), doc2.select_nodes(STR("*")));
xpath_node_set ns = doc.select_nodes(STR("$var1 | $var2 | node"), &set);
ns.sort();
CHECK(ns.size() == 3);
CHECK(ns[0] != ns[1] && ns[0] != ns[2]);
xml_node n0 = doc.child(STR("node")), n1 = doc1.child(STR("node")), n2 = doc2.child(STR("node"));
CHECK(n0 == ns[0].node() || n0 == ns[1].node() || n0 == ns[2].node());
CHECK(n1 == ns[0].node() || n1 == ns[1].node() || n1 == ns[2].node());
CHECK(n2 == ns[0].node() || n2 == ns[1].node() || n2 == ns[2].node());
}
TEST(xpath_variables_long_name)
{
xpath_variable_set set;
set.set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &set, true);
}
TEST_XML(xpath_variables_select, "<node attr='1'/><node attr='2'/>")
{
xpath_variable_set set;
set.set(STR("one"), 1.0);
xpath_node_set ns = doc.select_nodes(STR("node[@attr=$one+1]"), &set);
CHECK(ns.size() == 1 && ns[0].node() == doc.last_child());
xpath_node n = doc.select_single_node(STR("node[@attr=$one+1]"), &set);
CHECK(n == ns[0]);
}
TEST(xpath_variables_empty_name)
{
xpath_variable_set set;
CHECK(!set.add(STR(""), xpath_type_number));
}
TEST_XML(xpath_variables_inside_filter, "<node key='1' value='2'/><node key='2' value='1'/><node key='1' value='1'/>")
{
xpath_variable_set set;
set.set(STR("one"), 1.0);
xpath_node_set ns = doc.select_nodes(STR("(node[@key = $one])[@value = $one]"), &set);
CHECK(ns.size() == 1 && ns[0].node() == doc.last_child());
}
TEST_XML(xpath_variables_step, "<node><child/><child/><child><child/></child></node>")
{
xpath_variable_set set;
set.set(STR("root"), doc.select_nodes(STR("node")));
CHECK_XPATH_NODESET_VAR(xml_node(), STR("$root/child"), &set) % 3 % 4 % 5;
CHECK_XPATH_NODESET_VAR(xml_node(), STR("$root//child"), &set) % 3 % 4 % 5 % 6;
}
TEST_XML(xpath_variables_index, "<node><child/><child/><child><child/></child></node>")
{
xpath_variable_set set;
set.set(STR("index"), 2.0);
CHECK_XPATH_NODESET_VAR(doc, STR("node/child[$index]"), &set) % 4;
CHECK_XPATH_NODESET_VAR(doc, STR("node/child[position()=$index]"), &set) % 4;
}
TEST(xpath_variables_qname)
{
xpath_variable_set set;
set.set(STR("foo:bar"), true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$foo:bar"), &set, true);
}
TEST(xpath_variables_name_error)
{
xpath_variable_set set;
set.set(STR("foo:"), true);
set.set(STR(":bar"), true);
set.set(STR("foo:*"), true);
set.set(STR("foo"), true);
set.set(STR("3"), true);
CHECK_XPATH_FAIL_VAR(STR("$foo:"), &set);
CHECK_XPATH_FAIL_VAR(STR("$:bar"), &set);
CHECK_XPATH_FAIL_VAR(STR("$foo:*"), &set);
CHECK_XPATH_FAIL_VAR(STR("$foo:bar:baz"), &set);
CHECK_XPATH_FAIL_VAR(STR("$ foo"), &set);
CHECK_XPATH_FAIL_VAR(STR("$3"), &set);
}
TEST(xpath_variables_empty_string)
{
xpath_variable_set set;
set.add(STR("empty"), xpath_type_string);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$empty = substring-before('a', 'z')"), &set, true);
}
TEST(xpath_variables_name_underscore)
{
xpath_variable_set set;
set.set(STR("_foo_bar"), true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("$_foo_bar"), &set, true);
}
TEST(xpath_variables_name_case)
{
xpath_variable_set set;
set.set(STR("i"), 5.0);
set.set(STR("I"), 2.0);
CHECK_XPATH_NUMBER_VAR(xml_node(), STR("$i div $I"), &set, 2.5);
}
TEST(xpath_variables_name_unicode)
{
#ifdef PUGIXML_WCHAR_MODE
#ifdef U_LITERALS
const char_t* name = L"\u0400\u203D";
#else
const char_t* name = L"\x0400\x203D";
#endif
#else
const char_t* name = "\xd0\x80\xe2\x80\xbd";
#endif
xpath_variable_set set;
set.set(name, STR("value"));
std::basic_string<char_t> var = STR("$");
var += name;
CHECK_XPATH_STRING_VAR(xml_node(), var.c_str(), &set, STR("value"));
}
TEST_XML(xpath_variables_count_sum, "<node><c1>12</c1><c2>23</c2><c3>34</c3></node>")
{
xpath_variable_set set;
set.set(STR("c12"), doc.select_nodes(STR("node/c1 | node/c2")));
set.set(STR("c3"), doc.select_nodes(STR("node/c3")));
set.set(STR("c"), doc.select_nodes(STR("node/*")));
CHECK_XPATH_NUMBER_VAR(xml_node(), STR("sum($c12) * count($c) - sum($c3)"), &set, 71);
}
#endif