Integrated changes from unicode branch to trunk
git-svn-id: http://pugixml.googlecode.com/svn/trunk@383 99668b35-9821-0410-8761-19e4c4f06640
This commit is contained in:
parent
efee7df3f4
commit
f542c5ebb8
60 changed files with 5847 additions and 2882 deletions
19
Jamfile.jam
19
Jamfile.jam
|
@ -28,8 +28,8 @@ if ( ! $(configuration) )
|
|||
configuration = "debug" ;
|
||||
}
|
||||
|
||||
# remove empty define
|
||||
defines -= "" ;
|
||||
# split defines into list
|
||||
defines = [ Split $(defines) : ',' ] ;
|
||||
|
||||
# options
|
||||
if ( $(defines) )
|
||||
|
@ -41,23 +41,24 @@ else
|
|||
BUILD = build/$(toolset)/standard/$(configuration) ;
|
||||
}
|
||||
|
||||
if ( $(toolset:I=^mingw) )
|
||||
if ( $(toolset:I=^mingw) || $(toolset) = gcc )
|
||||
{
|
||||
CCFLAGS = -fprofile-arcs -ftest-coverage ;
|
||||
LDFLAGS = -fprofile-arcs ;
|
||||
GCOVFLAGS = -n ;
|
||||
|
||||
if ( $(toolset) = mingw44 )
|
||||
{
|
||||
GCOVFLAGS += -o $(BUILD)/src ; # because stupid gcov can't find files via relative paths any more
|
||||
}
|
||||
GCOVFLAGS += -o $(BUILD)/src ; # because stupid gcov can't find files via relative paths
|
||||
}
|
||||
|
||||
# rules
|
||||
include "Jamrules.jam" ;
|
||||
|
||||
# enable dependency cache
|
||||
DEPCACHE.standard = build/.depcache ;
|
||||
|
||||
# targets
|
||||
Library pugixml : src/pugixml.cpp src/pugixpath.cpp ;
|
||||
Application tests : tests/main.cpp [ Glob tests : test_*.cpp ] : pugixml ;
|
||||
Application tests : [ Glob tests : *.cpp ] : pugixml ;
|
||||
Test run_tests : tests ;
|
||||
Coverage coverage : run_tests ;
|
||||
Coverage coverage : pugixml ;
|
||||
Depends coverage : run_tests ;
|
||||
|
|
26
Jamrules.jam
26
Jamrules.jam
|
@ -8,7 +8,7 @@ if ( $(toolset:I=^mingw) || $(toolset) = "gcc" )
|
|||
}
|
||||
else
|
||||
{
|
||||
GCCPATH = "%$(toolset)_PATH%\bin\\" ;
|
||||
GCCPATH = "%$(toolset)_PATH%\\bin\\" ;
|
||||
}
|
||||
|
||||
CCFLAGS += -D$(defines) ;
|
||||
|
@ -39,12 +39,12 @@ if ( $(toolset:I=^mingw) || $(toolset) = "gcc" )
|
|||
|
||||
actions LinkAction
|
||||
{
|
||||
"$(GCCPATH)g++" $(>) -o $(<) -static-libgcc $(LDFLAGS)
|
||||
"$(GCCPATH)g++" $(>) -o $(<) -static-libgcc -static $(LDFLAGS)
|
||||
}
|
||||
|
||||
actions CoverageAction
|
||||
actions maxtargets 1 CoverageAction
|
||||
{
|
||||
"$(GCCPATH)gcov" $(>:\\) $(GCOVFLAGS) | perl tests/gcov-filter.pl
|
||||
"$(GCCPATH)gcov" $(>) $(GCOVFLAGS) | perl tests/gcov-filter.pl
|
||||
}
|
||||
}
|
||||
else if ( $(toolset:I=^msvc) )
|
||||
|
@ -69,6 +69,15 @@ else if ( $(toolset:I=^msvc) )
|
|||
CCFLAGS += /W3 ; # lots of warnings at W4 in standard library
|
||||
}
|
||||
|
||||
if ( $(toolset) = msvc7 || $(toolset) = msvc71 || $(toolset) = msvc8 )
|
||||
{
|
||||
CCFLAGS += "/I\"%$(toolset)_PATH%\\PlatformSDK\\include\"" ;
|
||||
}
|
||||
else if ( $(toolset) != msvc6 )
|
||||
{
|
||||
CCFLAGS += "/I\"%WINSDK_PATH%\\Include\"" ;
|
||||
}
|
||||
|
||||
if ( ! ( PUGIXML_NO_EXCEPTIONS in $(defines) ) )
|
||||
{
|
||||
CCFLAGS += /EHsc ;
|
||||
|
@ -107,7 +116,7 @@ else if ( $(toolset:I=^msvc) )
|
|||
|
||||
actions LinkAction
|
||||
{
|
||||
"%$(toolset)_PATH%\bin$(postfix)\link.exe" /SUBSYSTEM:CONSOLE /NOLOGO /OUT:$(<) $(>) /LIBPATH:"%$(toolset)_PATH%\lib$(postfix)" /LIBPATH:"%$(toolset)_PATH%\PlatformSDK\lib" /LIBPATH:"%WINSDK_PATH%\Lib$(sdk_postfix)" $(LDFLAGS)
|
||||
"%$(toolset)_PATH%\bin$(postfix)\link.exe" /SUBSYSTEM:CONSOLE /NOLOGO /OUT:$(<) /PDB:$(<:S=.pdb) $(>) /LIBPATH:"%$(toolset)_PATH%\lib$(postfix)" /LIBPATH:"%$(toolset)_PATH%\PlatformSDK\lib" /LIBPATH:"%WINSDK_PATH%\Lib$(sdk_postfix)" $(LDFLAGS)
|
||||
}
|
||||
|
||||
actions CoverageAction
|
||||
|
@ -136,7 +145,7 @@ else if ( $(toolset) = "ic8" )
|
|||
|
||||
actions ObjectAction
|
||||
{
|
||||
"%$(toolset)_PATH%\bin\icl.exe" /W4 /WX /Wport /Qwd981,444,280,383,909,304,167,177 /I"%$(msvc)_PATH%\include" /I"%$(toolset)_PATH%\include" /c $(>) /Fo$(<) /nologo $(CCFLAGS)
|
||||
"%$(toolset)_PATH%\bin\icl.exe" /W4 /WX /Wport /Qwd981,444,280,383,909,304,167,177,1419 /I"%$(msvc)_PATH%\include" /I"%$(msvc)_PATH%\PlatformSDK\Include" /I"%$(toolset)_PATH%\include" /c $(>) /Fo$(<) /nologo $(CCFLAGS)
|
||||
}
|
||||
|
||||
actions LibraryAction
|
||||
|
@ -183,7 +192,7 @@ else if ( $(toolset:I=^dmc) )
|
|||
|
||||
actions LinkAction
|
||||
{
|
||||
"%$(toolset)_PATH%\bin\link.exe" $(>:\\) , $(<:\\) , nul , $(LDFLAGS:\\)
|
||||
"%$(toolset)_PATH%\bin\link.exe" $(>:\\) , $(<:\\) , nul , $(LDFLAGS:\\) -L/co/ma
|
||||
}
|
||||
|
||||
actions CoverageAction
|
||||
|
@ -400,6 +409,9 @@ rule CleanCoverage TARGET
|
|||
# clean object files
|
||||
local FILES = $($(SOURCE)_objects:S=.gcda) ;
|
||||
|
||||
# disable "independent target" warnings
|
||||
NotFile $(FILES) ;
|
||||
|
||||
DeleteAction $(CLEAN_TARGET) : $(FILES) ;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#ifndef HEADER_PUGICONFIG_HPP
|
||||
#define HEADER_PUGICONFIG_HPP
|
||||
|
||||
// Uncomment this to enable wchar_t mode
|
||||
// #define PUGIXML_WCHAR_MODE
|
||||
|
||||
// Uncomment this to disable STL
|
||||
// #define PUGIXML_NO_STL
|
||||
|
||||
|
|
358
src/pugiutf.hpp
Normal file
358
src/pugiutf.hpp
Normal file
|
@ -0,0 +1,358 @@
|
|||
/**
|
||||
* pugixml parser - version 0.5
|
||||
* --------------------------------------------------------
|
||||
* Copyright (C) 2006-2009, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* Report bugs and download new versions at http://code.google.com/p/pugixml/
|
||||
*
|
||||
* This library is distributed under the MIT License. See notice at the end
|
||||
* of this file.
|
||||
*
|
||||
* This work is based on the pugxml parser, which is:
|
||||
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||
*/
|
||||
|
||||
#ifndef HEADER_PUGIUTF_HPP
|
||||
#define HEADER_PUGIUTF_HPP
|
||||
|
||||
namespace pugi
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
typedef unsigned char char8_t;
|
||||
typedef unsigned short char16_t;
|
||||
typedef unsigned int char32_t;
|
||||
|
||||
inline char16_t endian_swap(char16_t value)
|
||||
{
|
||||
return static_cast<char16_t>(((value & 0xff) << 8) | (value >> 8));
|
||||
}
|
||||
|
||||
inline char32_t endian_swap(char32_t value)
|
||||
{
|
||||
return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24);
|
||||
}
|
||||
|
||||
struct utf8_counter
|
||||
{
|
||||
typedef size_t value_type;
|
||||
|
||||
static value_type low(value_type result, char32_t ch)
|
||||
{
|
||||
// U+0000..U+007F
|
||||
if (ch < 0x80) return result + 1;
|
||||
// U+0080..U+07FF
|
||||
else if (ch < 0x800) return result + 2;
|
||||
// U+0800..U+FFFF
|
||||
else return result + 3;
|
||||
}
|
||||
|
||||
static value_type high(value_type result, char32_t)
|
||||
{
|
||||
// U+10000..U+10FFFF
|
||||
return result + 4;
|
||||
}
|
||||
};
|
||||
|
||||
struct utf8_writer
|
||||
{
|
||||
typedef char8_t* value_type;
|
||||
|
||||
static value_type low(value_type result, char32_t ch)
|
||||
{
|
||||
// U+0000..U+007F
|
||||
if (ch < 0x80)
|
||||
{
|
||||
*result = static_cast<char8_t>(ch);
|
||||
return result + 1;
|
||||
}
|
||||
// U+0080..U+07FF
|
||||
else if (ch < 0x800)
|
||||
{
|
||||
result[0] = static_cast<char8_t>(0xC0 | (ch >> 6));
|
||||
result[1] = static_cast<char8_t>(0x80 | (ch & 0x3F));
|
||||
return result + 2;
|
||||
}
|
||||
// U+0800..U+FFFF
|
||||
else
|
||||
{
|
||||
result[0] = static_cast<char8_t>(0xE0 | (ch >> 12));
|
||||
result[1] = static_cast<char8_t>(0x80 | ((ch >> 6) & 0x3F));
|
||||
result[2] = static_cast<char8_t>(0x80 | (ch & 0x3F));
|
||||
return result + 3;
|
||||
}
|
||||
}
|
||||
|
||||
static value_type high(value_type result, char32_t ch)
|
||||
{
|
||||
// U+10000..U+10FFFF
|
||||
result[0] = static_cast<char8_t>(0xF0 | (ch >> 18));
|
||||
result[1] = static_cast<char8_t>(0x80 | ((ch >> 12) & 0x3F));
|
||||
result[2] = static_cast<char8_t>(0x80 | ((ch >> 6) & 0x3F));
|
||||
result[3] = static_cast<char8_t>(0x80 | (ch & 0x3F));
|
||||
return result + 4;
|
||||
}
|
||||
|
||||
static value_type any(value_type result, char32_t ch)
|
||||
{
|
||||
return (ch < 0x10000) ? low(result, ch) : high(result, ch);
|
||||
}
|
||||
};
|
||||
|
||||
struct utf16_counter
|
||||
{
|
||||
typedef size_t value_type;
|
||||
|
||||
static value_type low(value_type result, char32_t)
|
||||
{
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
static value_type high(value_type result, char32_t)
|
||||
{
|
||||
return result + 2;
|
||||
}
|
||||
};
|
||||
|
||||
struct utf16_writer
|
||||
{
|
||||
typedef char16_t* value_type;
|
||||
|
||||
static value_type low(value_type result, char32_t ch)
|
||||
{
|
||||
*result = static_cast<char16_t>(ch);
|
||||
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
static value_type high(value_type result, char32_t ch)
|
||||
{
|
||||
char32_t msh = (char32_t)(ch - 0x10000) >> 10;
|
||||
char32_t lsh = (char32_t)(ch - 0x10000) & 0x3ff;
|
||||
|
||||
result[0] = static_cast<char16_t>(0xD800 + msh);
|
||||
result[1] = static_cast<char16_t>(0xDC00 + lsh);
|
||||
|
||||
return result + 2;
|
||||
}
|
||||
|
||||
static value_type any(value_type result, char32_t ch)
|
||||
{
|
||||
return (ch < 0x10000) ? low(result, ch) : high(result, ch);
|
||||
}
|
||||
};
|
||||
|
||||
struct utf32_counter
|
||||
{
|
||||
typedef size_t value_type;
|
||||
|
||||
static value_type low(value_type result, char32_t)
|
||||
{
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
static value_type high(value_type result, char32_t)
|
||||
{
|
||||
return result + 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct utf32_writer
|
||||
{
|
||||
typedef char32_t* value_type;
|
||||
|
||||
static value_type low(value_type result, char32_t ch)
|
||||
{
|
||||
*result = ch;
|
||||
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
static value_type high(value_type result, char32_t ch)
|
||||
{
|
||||
*result = ch;
|
||||
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
static value_type any(value_type result, char32_t ch)
|
||||
{
|
||||
*result = ch;
|
||||
|
||||
return result + 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t size> struct wchar_selector;
|
||||
|
||||
template <> struct wchar_selector<2>
|
||||
{
|
||||
typedef char16_t type;
|
||||
typedef utf16_counter counter;
|
||||
typedef utf16_writer writer;
|
||||
};
|
||||
|
||||
template <> struct wchar_selector<4>
|
||||
{
|
||||
typedef char32_t type;
|
||||
typedef utf32_counter counter;
|
||||
typedef utf32_writer writer;
|
||||
};
|
||||
|
||||
typedef wchar_selector<sizeof(wchar_t)>::counter wchar_counter;
|
||||
typedef wchar_selector<sizeof(wchar_t)>::writer wchar_writer;
|
||||
|
||||
template <typename Traits> static inline typename Traits::value_type decode_utf8_block(const char8_t* data, size_t size, typename Traits::value_type result, Traits = Traits())
|
||||
{
|
||||
const char8_t utf8_byte_mask = 0x3f;
|
||||
|
||||
const char8_t* end = data + size;
|
||||
|
||||
while (data < end)
|
||||
{
|
||||
char8_t lead = *data;
|
||||
|
||||
// 0xxxxxxx -> U+0000..U+007F
|
||||
if (lead < 0x80)
|
||||
{
|
||||
result = Traits::low(result, lead);
|
||||
data += 1;
|
||||
}
|
||||
// 110xxxxx -> U+0080..U+07FF
|
||||
else if ((unsigned)(lead - 0xC0) < 0x20 && data + 1 < end && (data[1] & 0xc0) == 0x80)
|
||||
{
|
||||
result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
|
||||
data += 2;
|
||||
}
|
||||
// 1110xxxx -> U+0800-U+FFFF
|
||||
else if ((unsigned)(lead - 0xE0) < 0x10 && data + 2 < end && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
|
||||
{
|
||||
result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
|
||||
data += 3;
|
||||
}
|
||||
// 11110xxx -> U+10000..U+10FFFF
|
||||
else if ((unsigned)(lead - 0xF0) < 0x08 && data + 3 < end && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
|
||||
{
|
||||
result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
|
||||
data += 4;
|
||||
}
|
||||
// 10xxxxxx or 11111xxx -> invalid
|
||||
else
|
||||
{
|
||||
data += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Traits, typename opt1> static inline typename Traits::value_type decode_utf16_block(const char16_t* data, size_t size, typename Traits::value_type result, opt1, Traits = Traits())
|
||||
{
|
||||
const bool swap = opt1::o1;
|
||||
|
||||
const char16_t* end = data + size;
|
||||
|
||||
while (data < end)
|
||||
{
|
||||
char16_t lead = swap ? endian_swap(*data) : *data;
|
||||
|
||||
// U+0000..U+D7FF
|
||||
if (lead < 0xD800)
|
||||
{
|
||||
result = Traits::low(result, lead);
|
||||
data += 1;
|
||||
}
|
||||
// U+E000..U+FFFF
|
||||
else if ((unsigned)(lead - 0xE000) < 0x2000)
|
||||
{
|
||||
result = Traits::low(result, lead);
|
||||
data += 1;
|
||||
}
|
||||
// surrogate pair lead
|
||||
else if ((unsigned)(lead - 0xD800) < 0x400 && data + 1 < end)
|
||||
{
|
||||
char16_t next = swap ? endian_swap(data[1]) : data[1];
|
||||
|
||||
if ((unsigned)(next - 0xDC00) < 0x400)
|
||||
{
|
||||
result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff));
|
||||
data += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
data += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Traits, typename opt1> static inline typename Traits::value_type decode_utf32_block(const char32_t* data, size_t size, typename Traits::value_type result, opt1, Traits = Traits())
|
||||
{
|
||||
const bool swap = opt1::o1;
|
||||
|
||||
const char32_t* end = data + size;
|
||||
|
||||
while (data < end)
|
||||
{
|
||||
char32_t lead = swap ? endian_swap(*data) : *data;
|
||||
|
||||
// U+0000..U+FFFF
|
||||
if (lead < 0x10000)
|
||||
{
|
||||
result = Traits::low(result, lead);
|
||||
data += 1;
|
||||
}
|
||||
// U+10000..U+10FFFF
|
||||
else
|
||||
{
|
||||
result = Traits::high(result, lead);
|
||||
data += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T> inline void convert_utf_endian_swap(T* result, const T* data, size_t length)
|
||||
{
|
||||
for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]);
|
||||
}
|
||||
|
||||
inline void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length)
|
||||
{
|
||||
for (size_t i = 0; i < length; ++i) result[i] = static_cast<wchar_t>(endian_swap(static_cast<wchar_selector<sizeof(wchar_t)>::type>(data[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copyright (c) 2006-2009 Arseny Kapoulkine
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
2148
src/pugixml.cpp
2148
src/pugixml.cpp
File diff suppressed because it is too large
Load diff
338
src/pugixml.hpp
338
src/pugixml.hpp
|
@ -17,8 +17,25 @@
|
|||
#include "pugiconfig.hpp"
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
# include <string>
|
||||
# include <iosfwd>
|
||||
#include <exception>
|
||||
|
||||
namespace std
|
||||
{
|
||||
struct bidirectional_iterator_tag;
|
||||
|
||||
// Borland C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions
|
||||
template <class _Ty> class allocator;
|
||||
template <class _Ty> struct char_traits;
|
||||
template <class _Elem, class _Traits> class basic_istream;
|
||||
template <class _Elem, class _Traits> class basic_ostream;
|
||||
template <class _Elem, class _Traits, class _Ax> class basic_string;
|
||||
|
||||
// Digital Mars compiler has a bug which requires a forward declaration for explicit instantiation (otherwise type selection is messed up later, producing link errors)
|
||||
// Also note that we have to declare char_traits as a class here, since it's defined that way
|
||||
#ifdef __DMC__
|
||||
template <> class char_traits<char>;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// No XPath without STL
|
||||
|
@ -45,13 +62,39 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
// Character interface macros
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
# define PUGIXML_TEXT(t) L ## t
|
||||
|
||||
namespace pugi
|
||||
{
|
||||
typedef wchar_t char_t;
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > string_t;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
# define PUGIXML_TEXT(t) t
|
||||
|
||||
namespace pugi
|
||||
{
|
||||
typedef char char_t;
|
||||
|
||||
# ifndef PUGIXML_NO_STL
|
||||
// gcc3.4 has a bug which prevents string_t instantiation using char_t, so we have to use char type explicitly
|
||||
typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string_t;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Helpers for inline implementation
|
||||
namespace pugi
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
int PUGIXML_FUNCTION strcmp(const char*, const char*);
|
||||
int PUGIXML_FUNCTION strcmpwild(const char*, const char*);
|
||||
bool PUGIXML_FUNCTION strequal(const char_t*, const char_t*);
|
||||
bool PUGIXML_FUNCTION strequalwild(const char_t*, const char_t*);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,6 +242,24 @@ namespace pugi
|
|||
*/
|
||||
const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol;
|
||||
|
||||
/**
|
||||
* These flags determine the encoding of input data for XML document. Default mode is encoding_auto,
|
||||
* which means that document encoding is autodetected from BOM and necessary encoding conversions are
|
||||
* applied. You can override this mode by using any of the specific encodings.
|
||||
*/
|
||||
enum encoding_t
|
||||
{
|
||||
encoding_auto, //!< Auto-detect input encoding using BOM or </<? detection; use UTF8 if BOM is not found
|
||||
encoding_utf8, //!< UTF8 encoding
|
||||
encoding_utf16_le, //!< Little-endian UTF16
|
||||
encoding_utf16_be, //!< Big-endian UTF16
|
||||
encoding_utf16, //!< UTF16 with native endianness
|
||||
encoding_utf32_le, //!< Little-endian UTF32
|
||||
encoding_utf32_be, //!< Big-endian UTF32
|
||||
encoding_utf32, //!< UTF32 with native endianness
|
||||
encoding_wchar //!< The same encoding wchar_t has (either UTF16 or UTF32)
|
||||
};
|
||||
|
||||
// Formatting flags
|
||||
|
||||
/**
|
||||
|
@ -210,11 +271,11 @@ namespace pugi
|
|||
const unsigned int format_indent = 0x01;
|
||||
|
||||
/**
|
||||
* This flag determines if UTF-8 BOM is to be written to output stream.
|
||||
* This flag determines if encoding-specific BOM is to be written to output stream.
|
||||
*
|
||||
* This flag is off by default.
|
||||
*/
|
||||
const unsigned int format_write_bom_utf8 = 0x02;
|
||||
const unsigned int format_write_bom = 0x02;
|
||||
|
||||
/**
|
||||
* If this flag is on, no indentation is performed and no line breaks are written to output file.
|
||||
|
@ -281,7 +342,7 @@ namespace pugi
|
|||
xpath_allocator* m_alloc;
|
||||
xpath_ast_node* m_root;
|
||||
|
||||
void compile(const char* query);
|
||||
void compile(const char_t* query);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -290,7 +351,7 @@ namespace pugi
|
|||
*
|
||||
* \param query - string with XPath expression
|
||||
*/
|
||||
explicit xpath_query(const char* query);
|
||||
explicit xpath_query(const char_t* query);
|
||||
|
||||
/**
|
||||
* Dtor
|
||||
|
@ -335,7 +396,7 @@ namespace pugi
|
|||
* \param n - context node
|
||||
* \return evaluation result
|
||||
*/
|
||||
std::string evaluate_string(const xml_node& n) const;
|
||||
string_t evaluate_string(const xml_node& n) const;
|
||||
|
||||
/**
|
||||
* Evaluate expression as node set for the context node \a n.
|
||||
|
@ -401,12 +462,20 @@ namespace pugi
|
|||
*
|
||||
* \param stream - output stream object
|
||||
*/
|
||||
xml_writer_stream(std::ostream& stream);
|
||||
xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream);
|
||||
|
||||
/**
|
||||
* Construct writer instance
|
||||
*
|
||||
* \param stream - output stream object
|
||||
*/
|
||||
xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream);
|
||||
|
||||
virtual void write(const void* data, size_t size);
|
||||
|
||||
private:
|
||||
std::ostream* stream;
|
||||
std::basic_ostream<char, std::char_traits<char> >* narrow_stream;
|
||||
std::basic_ostream<wchar_t, std::char_traits<wchar_t> >* wide_stream;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -559,7 +628,7 @@ namespace pugi
|
|||
* \param rhs - new attribute value
|
||||
* \return self
|
||||
*/
|
||||
xml_attribute& operator=(const char* rhs);
|
||||
xml_attribute& operator=(const char_t* rhs);
|
||||
|
||||
/**
|
||||
* Set attribute value to \a rhs.
|
||||
|
@ -599,7 +668,7 @@ namespace pugi
|
|||
* \param rhs - new attribute name
|
||||
* \return success flag (call fails if attribute is empty or there is not enough memory)
|
||||
*/
|
||||
bool set_name(const char* rhs);
|
||||
bool set_name(const char_t* rhs);
|
||||
|
||||
/**
|
||||
* Set attribute value to \a rhs.
|
||||
|
@ -607,7 +676,7 @@ namespace pugi
|
|||
* \param rhs - new attribute value
|
||||
* \return success flag (call fails if attribute is empty or there is not enough memory)
|
||||
*/
|
||||
bool set_value(const char* rhs);
|
||||
bool set_value(const char_t* rhs);
|
||||
|
||||
/**
|
||||
* Set attribute value to \a rhs.
|
||||
|
@ -655,14 +724,14 @@ namespace pugi
|
|||
*
|
||||
* \return attribute name, or "" if attribute is empty
|
||||
*/
|
||||
const char* name() const;
|
||||
const char_t* name() const;
|
||||
|
||||
/**
|
||||
* Get attribute value.
|
||||
*
|
||||
* \return attribute value, or "" if attribute is empty
|
||||
*/
|
||||
const char* value() const;
|
||||
const char_t* value() const;
|
||||
};
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
|
@ -825,14 +894,14 @@ namespace pugi
|
|||
*
|
||||
* \return node name, if any; "" otherwise
|
||||
*/
|
||||
const char* name() const;
|
||||
const char_t* name() const;
|
||||
|
||||
/**
|
||||
* Get node value (comment/PI/PCDATA/CDATA contents, depending on node type)
|
||||
*
|
||||
* \return node value, if any; "" otherwise
|
||||
*/
|
||||
const char* value() const;
|
||||
const char_t* value() const;
|
||||
|
||||
/**
|
||||
* Get child with the specified name
|
||||
|
@ -840,7 +909,7 @@ namespace pugi
|
|||
* \param name - child name
|
||||
* \return child with the specified name, if any; empty node otherwise
|
||||
*/
|
||||
xml_node child(const char* name) const;
|
||||
xml_node child(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get child with the name that matches specified pattern
|
||||
|
@ -848,7 +917,7 @@ namespace pugi
|
|||
* \param name - child name pattern
|
||||
* \return child with the name that matches pattern, if any; empty node otherwise
|
||||
*/
|
||||
xml_node child_w(const char* name) const;
|
||||
xml_node child_w(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get attribute with the specified name
|
||||
|
@ -856,7 +925,7 @@ namespace pugi
|
|||
* \param name - attribute name
|
||||
* \return attribute with the specified name, if any; empty attribute otherwise
|
||||
*/
|
||||
xml_attribute attribute(const char* name) const;
|
||||
xml_attribute attribute(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get attribute with the name that matches specified pattern
|
||||
|
@ -864,7 +933,7 @@ namespace pugi
|
|||
* \param name - attribute name pattern
|
||||
* \return attribute with the name that matches pattern, if any; empty attribute otherwise
|
||||
*/
|
||||
xml_attribute attribute_w(const char* name) const;
|
||||
xml_attribute attribute_w(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get first of following sibling nodes with the specified name
|
||||
|
@ -872,7 +941,7 @@ namespace pugi
|
|||
* \param name - sibling name
|
||||
* \return node with the specified name, if any; empty node otherwise
|
||||
*/
|
||||
xml_node next_sibling(const char* name) const;
|
||||
xml_node next_sibling(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get first of the following sibling nodes with the name that matches specified pattern
|
||||
|
@ -880,7 +949,7 @@ namespace pugi
|
|||
* \param name - sibling name pattern
|
||||
* \return node with the name that matches pattern, if any; empty node otherwise
|
||||
*/
|
||||
xml_node next_sibling_w(const char* name) const;
|
||||
xml_node next_sibling_w(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get following sibling
|
||||
|
@ -895,7 +964,7 @@ namespace pugi
|
|||
* \param name - sibling name
|
||||
* \return node with the specified name, if any; empty node otherwise
|
||||
*/
|
||||
xml_node previous_sibling(const char* name) const;
|
||||
xml_node previous_sibling(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get first of the preceding sibling nodes with the name that matches specified pattern
|
||||
|
@ -903,7 +972,7 @@ namespace pugi
|
|||
* \param name - sibling name pattern
|
||||
* \return node with the name that matches pattern, if any; empty node otherwise
|
||||
*/
|
||||
xml_node previous_sibling_w(const char* name) const;
|
||||
xml_node previous_sibling_w(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get preceding sibling
|
||||
|
@ -931,7 +1000,7 @@ namespace pugi
|
|||
*
|
||||
* \return child value of current node, if any; "" otherwise
|
||||
*/
|
||||
const char* child_value() const;
|
||||
const char_t* child_value() const;
|
||||
|
||||
/**
|
||||
* Get child value of child with specified name. \see child_value
|
||||
|
@ -940,7 +1009,7 @@ namespace pugi
|
|||
* \param name - child name
|
||||
* \return child value of specified child node, if any; "" otherwise
|
||||
*/
|
||||
const char* child_value(const char* name) const;
|
||||
const char_t* child_value(const char_t* name) const;
|
||||
|
||||
/**
|
||||
* Get child value of child with name that matches the specified pattern. \see child_value
|
||||
|
@ -949,7 +1018,7 @@ namespace pugi
|
|||
* \param name - child name pattern
|
||||
* \return child value of specified child node, if any; "" otherwise
|
||||
*/
|
||||
const char* child_value_w(const char* name) const;
|
||||
const char_t* child_value_w(const char_t* name) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -958,7 +1027,7 @@ namespace pugi
|
|||
* \param rhs - new node name
|
||||
* \return success flag (call fails if node is of the wrong type or there is not enough memory)
|
||||
*/
|
||||
bool set_name(const char* rhs);
|
||||
bool set_name(const char_t* rhs);
|
||||
|
||||
/**
|
||||
* Set node value to \a rhs (for PI/PCDATA/CDATA/comment nodes). \see value
|
||||
|
@ -966,7 +1035,7 @@ namespace pugi
|
|||
* \param rhs - new node value
|
||||
* \return success flag (call fails if node is of the wrong type or there is not enough memory)
|
||||
*/
|
||||
bool set_value(const char* rhs);
|
||||
bool set_value(const char_t* rhs);
|
||||
|
||||
/**
|
||||
* Add attribute with specified name (for element nodes)
|
||||
|
@ -974,7 +1043,7 @@ namespace pugi
|
|||
* \param name - attribute name
|
||||
* \return added attribute, or empty attribute if there was an error (wrong node type)
|
||||
*/
|
||||
xml_attribute append_attribute(const char* name);
|
||||
xml_attribute append_attribute(const char_t* name);
|
||||
|
||||
/**
|
||||
* Insert attribute with specified name after \a attr (for element nodes)
|
||||
|
@ -983,7 +1052,7 @@ namespace pugi
|
|||
* \param attr - attribute to insert a new one after
|
||||
* \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node)
|
||||
*/
|
||||
xml_attribute insert_attribute_after(const char* name, const xml_attribute& attr);
|
||||
xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);
|
||||
|
||||
/**
|
||||
* Insert attribute with specified name before \a attr (for element nodes)
|
||||
|
@ -992,7 +1061,7 @@ namespace pugi
|
|||
* \param attr - attribute to insert a new one before
|
||||
* \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node)
|
||||
*/
|
||||
xml_attribute insert_attribute_before(const char* name, const xml_attribute& attr);
|
||||
xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);
|
||||
|
||||
/**
|
||||
* Add a copy of the specified attribute (for element nodes)
|
||||
|
@ -1084,7 +1153,7 @@ namespace pugi
|
|||
*
|
||||
* \param name - attribute name
|
||||
*/
|
||||
void remove_attribute(const char* name);
|
||||
void remove_attribute(const char_t* name);
|
||||
|
||||
/**
|
||||
* Remove specified child
|
||||
|
@ -1098,7 +1167,7 @@ namespace pugi
|
|||
*
|
||||
* \param name - child name
|
||||
*/
|
||||
void remove_child(const char* name);
|
||||
void remove_child(const char_t* name);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -1121,7 +1190,7 @@ namespace pugi
|
|||
* \param name - node name
|
||||
* \param it - output iterator (for example, std::back_insert_iterator (result of std::back_inserter))
|
||||
*/
|
||||
template <typename OutputIterator> void all_elements_by_name(const char* name, OutputIterator it) const
|
||||
template <typename OutputIterator> void all_elements_by_name(const char_t* name, OutputIterator it) const
|
||||
{
|
||||
if (!_root) return;
|
||||
|
||||
|
@ -1129,7 +1198,7 @@ namespace pugi
|
|||
{
|
||||
if (node.type() == node_element)
|
||||
{
|
||||
if (!impl::strcmp(name, node.name()))
|
||||
if (impl::strequal(name, node.name()))
|
||||
{
|
||||
*it = node;
|
||||
++it;
|
||||
|
@ -1146,7 +1215,7 @@ namespace pugi
|
|||
* \param name - node name pattern
|
||||
* \param it - output iterator (for example, std::back_insert_iterator (result of std::back_inserter))
|
||||
*/
|
||||
template <typename OutputIterator> void all_elements_by_name_w(const char* name, OutputIterator it) const
|
||||
template <typename OutputIterator> void all_elements_by_name_w(const char_t* name, OutputIterator it) const
|
||||
{
|
||||
if (!_root) return;
|
||||
|
||||
|
@ -1154,7 +1223,7 @@ namespace pugi
|
|||
{
|
||||
if (node.type() == node_element)
|
||||
{
|
||||
if (!impl::strcmpwild(name, node.name()))
|
||||
if (impl::strequalwild(name, node.name()))
|
||||
{
|
||||
*it = node;
|
||||
++it;
|
||||
|
@ -1246,7 +1315,7 @@ namespace pugi
|
|||
* \param attr_value - attribute value of child node
|
||||
* \return first matching child node, or empty node
|
||||
*/
|
||||
xml_node find_child_by_attribute(const char* name, const char* attr_name, const char* attr_value) const;
|
||||
xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
|
||||
|
||||
/**
|
||||
* Find child node with the specified name that has specified attribute (use pattern matching for node name and attribute name/value)
|
||||
|
@ -1256,7 +1325,7 @@ namespace pugi
|
|||
* \param attr_value - pattern for attribute value of child node
|
||||
* \return first matching child node, or empty node
|
||||
*/
|
||||
xml_node find_child_by_attribute_w(const char* name, const char* attr_name, const char* attr_value) const;
|
||||
xml_node find_child_by_attribute_w(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
|
||||
|
||||
/**
|
||||
* Find child node that has specified attribute
|
||||
|
@ -1265,7 +1334,7 @@ namespace pugi
|
|||
* \param attr_value - attribute value of child node
|
||||
* \return first matching child node, or empty node
|
||||
*/
|
||||
xml_node find_child_by_attribute(const char* attr_name, const char* attr_value) const;
|
||||
xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
|
||||
|
||||
/**
|
||||
* Find child node that has specified attribute (use pattern matching for attribute name/value)
|
||||
|
@ -1274,7 +1343,7 @@ namespace pugi
|
|||
* \param attr_value - pattern for attribute value of child node
|
||||
* \return first matching child node, or empty node
|
||||
*/
|
||||
xml_node find_child_by_attribute_w(const char* attr_name, const char* attr_value) const;
|
||||
xml_node find_child_by_attribute_w(const char_t* attr_name, const char_t* attr_value) const;
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
/**
|
||||
|
@ -1283,7 +1352,7 @@ namespace pugi
|
|||
* \param delimiter - delimiter character to insert between element names
|
||||
* \return path string (e.g. '/bookstore/book/author').
|
||||
*/
|
||||
std::string path(char delimiter = '/') const;
|
||||
string_t path(char_t delimiter = '/') const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -1293,7 +1362,7 @@ namespace pugi
|
|||
* \param delimiter - delimiter character to use while tokenizing path
|
||||
* \return matching node, if any; empty node otherwise
|
||||
*/
|
||||
xml_node first_element_by_path(const char* path, char delimiter = '/') const;
|
||||
xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const;
|
||||
|
||||
/**
|
||||
* Recursively traverse subtree with xml_tree_walker
|
||||
|
@ -1313,7 +1382,7 @@ namespace pugi
|
|||
* \param query - query string
|
||||
* \return first node from the resulting node set by document order, or empty node if none found
|
||||
*/
|
||||
xpath_node select_single_node(const char* query) const;
|
||||
xpath_node select_single_node(const char_t* query) const;
|
||||
|
||||
/**
|
||||
* Select single node by evaluating XPath query
|
||||
|
@ -1329,7 +1398,7 @@ namespace pugi
|
|||
* \param query - query string
|
||||
* \return resulting node set
|
||||
*/
|
||||
xpath_node_set select_nodes(const char* query) const;
|
||||
xpath_node_set select_nodes(const char_t* query) const;
|
||||
|
||||
/**
|
||||
* Select node set by evaluating XPath query
|
||||
|
@ -1351,7 +1420,7 @@ namespace pugi
|
|||
* \param flags - formatting flags
|
||||
* \param depth - starting depth (used for indentation)
|
||||
*/
|
||||
void print(xml_writer& writer, const char* indent = "\t", unsigned int flags = format_default, unsigned int depth = 0) const;
|
||||
void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto, unsigned int depth = 0) const;
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
/**
|
||||
|
@ -1363,7 +1432,18 @@ namespace pugi
|
|||
* \param depth - starting depth (used for indentation)
|
||||
* \deprecated Use print() with xml_writer_stream instead
|
||||
*/
|
||||
void print(std::ostream& os, const char* indent = "\t", unsigned int flags = format_default, unsigned int depth = 0) const;
|
||||
void print(std::basic_ostream<char, std::char_traits<char> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto, unsigned int depth = 0) const;
|
||||
|
||||
/**
|
||||
* Print subtree to stream
|
||||
*
|
||||
* \param os - output stream
|
||||
* \param indent - indentation string
|
||||
* \param flags - formatting flags
|
||||
* \param depth - starting depth (used for indentation)
|
||||
* \deprecated Use print() with xml_writer_stream instead
|
||||
*/
|
||||
void print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -1388,17 +1468,7 @@ namespace pugi
|
|||
* It's a bidirectional iterator with value type 'xml_node'.
|
||||
*/
|
||||
class PUGIXML_CLASS xml_node_iterator
|
||||
#ifndef PUGIXML_NO_STL
|
||||
: public std::iterator<std::bidirectional_iterator_tag, xml_node>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4275) // C4251 and C4275 can be ignored for _Container_base, as per MSDN
|
||||
#endif
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
friend class xml_node;
|
||||
|
||||
private:
|
||||
|
@ -1409,6 +1479,18 @@ namespace pugi
|
|||
explicit xml_node_iterator(xml_node_struct* ref);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Iterator traits
|
||||
*/
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef xml_node value_type;
|
||||
typedef xml_node* pointer;
|
||||
typedef xml_node& reference;
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default ctor
|
||||
*/
|
||||
|
@ -1493,17 +1575,7 @@ namespace pugi
|
|||
* It's a bidirectional iterator with value type 'xml_attribute'.
|
||||
*/
|
||||
class PUGIXML_CLASS xml_attribute_iterator
|
||||
#ifndef PUGIXML_NO_STL
|
||||
: public std::iterator<std::bidirectional_iterator_tag, xml_attribute>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4275) // C4251 and C4275 can be ignored for _Container_base, as per MSDN
|
||||
#endif
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
friend class xml_node;
|
||||
|
||||
private:
|
||||
|
@ -1514,6 +1586,18 @@ namespace pugi
|
|||
explicit xml_attribute_iterator(xml_attribute_struct* ref);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Iterator traits
|
||||
*/
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef xml_attribute value_type;
|
||||
typedef xml_attribute* pointer;
|
||||
typedef xml_attribute& reference;
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default ctor
|
||||
*/
|
||||
|
@ -1657,12 +1741,6 @@ namespace pugi
|
|||
char data[memory_block_size];
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct used to distinguish parsing with ownership transfer from parsing without it.
|
||||
* \see xml_document::parse
|
||||
*/
|
||||
struct transfer_ownership_tag {};
|
||||
|
||||
/**
|
||||
* Parsing status enumeration, returned as part of xml_parse_result struct
|
||||
*/
|
||||
|
@ -1702,6 +1780,9 @@ namespace pugi
|
|||
/// Line in parser source which reported this
|
||||
unsigned int line;
|
||||
|
||||
/// Source document encoding
|
||||
encoding_t encoding;
|
||||
|
||||
/// Cast to bool operator
|
||||
operator bool() const
|
||||
{
|
||||
|
@ -1719,7 +1800,7 @@ namespace pugi
|
|||
class PUGIXML_CLASS xml_document: public xml_node
|
||||
{
|
||||
private:
|
||||
char* _buffer;
|
||||
char_t* _buffer;
|
||||
|
||||
xml_memory_block _memory;
|
||||
|
||||
|
@ -1749,17 +1830,26 @@ namespace pugi
|
|||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result load(std::istream& stream, unsigned int options = parse_default);
|
||||
|
||||
xml_parse_result load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
|
||||
/**
|
||||
* Load document from stream.
|
||||
*
|
||||
* \param stream - stream with xml data
|
||||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Load document from string.
|
||||
* Load document from string. String has to be zero-terminated. No encoding conversions are applied.
|
||||
*
|
||||
* \param contents - input string
|
||||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result load(const char* contents, unsigned int options = parse_default);
|
||||
xml_parse_result load(const char_t* contents, unsigned int options = parse_default);
|
||||
|
||||
/**
|
||||
* Load document from file
|
||||
|
@ -1768,32 +1858,43 @@ namespace pugi
|
|||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result load_file(const char* name, unsigned int options = parse_default);
|
||||
xml_parse_result load_file(const char* name, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
|
||||
|
||||
/**
|
||||
* Parse the given XML string in-situ.
|
||||
* The string is modified; you should ensure that string data will persist throughout the
|
||||
* document's lifetime. Although, document does not gain ownership over the string, so you
|
||||
* should free the memory occupied by it manually.
|
||||
* Load document from buffer
|
||||
*
|
||||
* \param xmlstr - readwrite string with xml data
|
||||
* \param contents - buffer contents
|
||||
* \param size - buffer size in bytes
|
||||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result parse(char* xmlstr, unsigned int options = parse_default);
|
||||
|
||||
xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
|
||||
|
||||
/**
|
||||
* Parse the given XML string in-situ (gains ownership).
|
||||
* The string is modified; document gains ownership over the string, so you don't have to worry
|
||||
* about it's lifetime.
|
||||
* Call example: doc.parse(transfer_ownership_tag(), string, options);
|
||||
* Load document from buffer in-situ.
|
||||
* The buffer is modified; you should ensure that buffer data will persist throughout the document's
|
||||
* lifetime. Document does not gain ownership over the buffer, so you should free the buffer memory manually.
|
||||
*
|
||||
* \param xmlstr - readwrite string with xml data
|
||||
* \param contents - buffer contents
|
||||
* \param size - buffer size in bytes
|
||||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result parse(const transfer_ownership_tag&, char* xmlstr, unsigned int options = parse_default);
|
||||
|
||||
xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
|
||||
|
||||
/**
|
||||
* Load document from buffer in-situ (gains buffer ownership).
|
||||
* The buffer is modified; you should ensure that buffer data will persist throughout the document's
|
||||
* lifetime. Document gains ownership over the buffer, so you should allocate the buffer with pugixml
|
||||
* allocation function.
|
||||
*
|
||||
* \param contents - buffer contents
|
||||
* \param size - buffer size in bytes
|
||||
* \param options - parsing options
|
||||
* \return parsing result
|
||||
*/
|
||||
xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
|
||||
|
||||
/**
|
||||
* Save XML to writer
|
||||
*
|
||||
|
@ -1801,7 +1902,27 @@ namespace pugi
|
|||
* \param indent - indentation string
|
||||
* \param flags - formatting flags
|
||||
*/
|
||||
void save(xml_writer& writer, const char* indent = "\t", unsigned int flags = format_default) const;
|
||||
void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto) const;
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
/**
|
||||
* Save XML to stream
|
||||
*
|
||||
* \param stream - output stream
|
||||
* \param indent - indentation string
|
||||
* \param flags - formatting flags
|
||||
*/
|
||||
void save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto) const;
|
||||
|
||||
/**
|
||||
* Save XML to stream
|
||||
*
|
||||
* \param stream - output stream
|
||||
* \param indent - indentation string
|
||||
* \param flags - formatting flags
|
||||
*/
|
||||
void save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Save XML to file
|
||||
|
@ -1811,7 +1932,7 @@ namespace pugi
|
|||
* \param flags - formatting flags
|
||||
* \return success flag
|
||||
*/
|
||||
bool save_file(const char* name, const char* indent = "\t", unsigned int flags = format_default) const;
|
||||
bool save_file(const char* name, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto) const;
|
||||
|
||||
/**
|
||||
* Compute document order for the whole tree
|
||||
|
@ -2063,20 +2184,20 @@ namespace pugi
|
|||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
/**
|
||||
* Convert utf16 to utf8
|
||||
* Convert wide string to utf8
|
||||
*
|
||||
* \param str - input UTF16 string
|
||||
* \param str - input wide string string
|
||||
* \return output UTF8 string
|
||||
*/
|
||||
std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str);
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str);
|
||||
|
||||
/**
|
||||
* Convert utf8 to utf16
|
||||
* Convert utf8 to wide string
|
||||
*
|
||||
* \param str - input UTF8 string
|
||||
* \return output UTF16 string
|
||||
* \return output wide string string
|
||||
*/
|
||||
std::wstring PUGIXML_FUNCTION as_utf16(const char* str);
|
||||
std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -2104,7 +2225,7 @@ namespace pugi
|
|||
* \param allocate - allocation function
|
||||
* \param deallocate - deallocation function
|
||||
*
|
||||
* \note XPath-related allocations, as well as allocations in functions that return std::string (xml_node::path, as_utf8, as_utf16)
|
||||
* \note XPath-related allocations, as well as allocations in functions that return std::string (xml_node::path, as_utf8, as_wide)
|
||||
* are not performed via these functions.
|
||||
* \note If you're using parse() with ownership transfer, you have to allocate the buffer you pass to parse() with allocation
|
||||
* function you set via this function.
|
||||
|
@ -2128,6 +2249,15 @@ namespace pugi
|
|||
deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function();
|
||||
}
|
||||
|
||||
#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
|
||||
namespace std
|
||||
{
|
||||
// Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier)
|
||||
std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_node_iterator&);
|
||||
std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_attribute_iterator&);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
89
tests/allocator.cpp
Normal file
89
tests/allocator.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
#include "allocator.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Low-level allocation functions
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# ifdef __MWERKS__
|
||||
# pragma ANSI_strict off // disable ANSI strictness to include windows.h
|
||||
# pragma cpp_extensions on // enable some extensions to include windows.h
|
||||
# endif
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t PAGE_SIZE = 4096;
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
|
||||
void* ptr = VirtualAlloc(0, aligned_size + PAGE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!ptr) return 0;
|
||||
|
||||
void* end = (char*)ptr + aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(end, PAGE_SIZE, PAGE_NOACCESS, &old_flags);
|
||||
|
||||
return (char*)end - size;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
|
||||
void* rptr = (char*)ptr + size - aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(rptr, aligned_size + PAGE_SIZE, PAGE_NOACCESS, &old_flags);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
(void)size;
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// High-level allocation functions
|
||||
void* memory_allocate(size_t size)
|
||||
{
|
||||
void* result = allocate(size + sizeof(size_t));
|
||||
if (!result) return 0;
|
||||
|
||||
memcpy(result, &size, sizeof(size_t));
|
||||
|
||||
return (size_t*)result + 1;
|
||||
}
|
||||
|
||||
size_t memory_size(void* ptr)
|
||||
{
|
||||
size_t result;
|
||||
memcpy(&result, (size_t*)ptr - 1, sizeof(size_t));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void memory_deallocate(void* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
|
||||
size_t size = memory_size(ptr);
|
||||
|
||||
deallocate((size_t*)ptr - 1, size + sizeof(size_t));
|
||||
}
|
||||
|
7
tests/allocator.hpp
Normal file
7
tests/allocator.hpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void* memory_allocate(size_t size);
|
||||
size_t memory_size(void* ptr);
|
||||
void memory_deallocate(void* ptr);
|
141
tests/autotest.pl
Normal file
141
tests/autotest.pl
Normal file
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
sub permute
|
||||
{
|
||||
my @defines = @_;
|
||||
my @result = ('');
|
||||
|
||||
foreach $define (@defines)
|
||||
{
|
||||
push @result, map { length($_) == 0 ? $define : "$_,$define" } @result;
|
||||
}
|
||||
|
||||
@result;
|
||||
}
|
||||
|
||||
$fast = (shift eq 'fast');
|
||||
@toolsets = ($^O =~ /win/i) ? (bcc, cw, dmc, ic8, mingw34, mingw44, mingw45, msvc6, msvc7, msvc71, msvc8, msvc9, msvc9_x64, msvc10) : (gcc);
|
||||
@configurations = (debug, release);
|
||||
@defines = (PUGIXML_NO_XPATH, PUGIXML_NO_EXCEPTIONS, PUGIXML_NO_STL, PUGIXML_WCHAR_MODE);
|
||||
@definesabbr = (noxpath, noexcept, nostl, wchar);
|
||||
|
||||
if ($fast)
|
||||
{
|
||||
@defines = (PUGIXML_WCHAR_MODE);
|
||||
@definesabbr = (wchar);
|
||||
}
|
||||
|
||||
@definesets = permute(@defines);
|
||||
|
||||
$fail = 0;
|
||||
|
||||
system("echo ### autotest begin >autotest.log");
|
||||
|
||||
%results = ();
|
||||
|
||||
foreach $toolset (@toolsets)
|
||||
{
|
||||
foreach $configuration (@configurations)
|
||||
{
|
||||
foreach $defineset (@definesets)
|
||||
{
|
||||
$defineabbr = $defineset;
|
||||
$defineabbr =~ s/,/ /g;
|
||||
|
||||
for ($i = 0; $i < $#definesabbr + 1; ++$i)
|
||||
{
|
||||
$defineabbr =~ s/$defines[$i]/$definesabbr[$i]/;
|
||||
}
|
||||
|
||||
if ($defineabbr !~ /noxpath/ && $defineabbr =~ /noexcept/) { next; }
|
||||
if ($defineabbr !~ /noxpath/ && $defineabbr =~ /nostl/) { next; }
|
||||
|
||||
print "*** testing $toolset/$configuration ($defineabbr) ... ***\n";
|
||||
|
||||
my $cmdline = "jam toolset=$toolset configuration=$configuration defines=$defineset";
|
||||
my $coverage_pugixml = 0;
|
||||
my $coverage_pugixpath = 0;
|
||||
|
||||
system("echo ^# $cmdline run_tests >>autotest.log");
|
||||
$result = system("$cmdline run_tests >>autotest.log");
|
||||
|
||||
# get coverage
|
||||
if ($result == 0 && $toolset =~ /mingw|gcc/)
|
||||
{
|
||||
$coverage = `$cmdline coverage`;
|
||||
|
||||
$coverage_pugixml = $1 if ($coverage =~ /pugixml\.cpp' executed:([^%]+)%/);
|
||||
$coverage_pugixpath = $1 if ($coverage =~ /pugixpath\.cpp' executed:([^%]+)%/);
|
||||
}
|
||||
|
||||
# record failures
|
||||
$fail = 1 if ($result != 0);
|
||||
|
||||
# print build report
|
||||
my $report = "";
|
||||
|
||||
if ($result == 0)
|
||||
{
|
||||
my $align = ($coverage_pugixml > 0 || $coverage_pugixpath > 0) ? 'left' : 'center';
|
||||
|
||||
$report .= "<td bgcolor='#00ff00' align='$align'>passed";
|
||||
|
||||
if ($coverage_pugixml > 0 || $coverage_pugixpath > 0)
|
||||
{
|
||||
$report .= " <font size='-2'>$coverage_pugixml% / $coverage_pugixpath%</font>";
|
||||
}
|
||||
|
||||
$report .= "</td>"
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$report .= "<td bgcolor='#ff0000' align='center'>failed</td>"
|
||||
}
|
||||
|
||||
$results{"$configuration $defineabbr"}{$toolset} = $report;
|
||||
}
|
||||
|
||||
last if ($fast);
|
||||
}
|
||||
}
|
||||
|
||||
system("echo ### autotest end >>autotest.log");
|
||||
|
||||
$date = scalar localtime;
|
||||
|
||||
$report = <<END;
|
||||
<html><head><title>pugixml autotest report</title></head><body>
|
||||
<h3>pugixml autotest report</h3>
|
||||
<table border=0 cellspacing=0 cellpadding=4>
|
||||
<tr><td></td>
|
||||
END
|
||||
|
||||
foreach $toolset (@toolsets)
|
||||
{
|
||||
$report .= "<th>$toolset</th>";
|
||||
}
|
||||
|
||||
$report .= "</tr>\n";
|
||||
|
||||
foreach $k (sort {$a cmp $b} keys %results)
|
||||
{
|
||||
$report .= "<tr><td>$k</td>";
|
||||
|
||||
foreach $toolset (@toolsets)
|
||||
{
|
||||
$report .= $results{$k}{$toolset};
|
||||
}
|
||||
|
||||
$report .= "</tr>\n";
|
||||
}
|
||||
|
||||
$report .= <<END;
|
||||
</table><br>
|
||||
Generated on $date
|
||||
</body></html>
|
||||
END
|
||||
|
||||
open FILE, ">autotest.html";
|
||||
print FILE $report;
|
||||
close FILE;
|
0
tests/data/empty.xml
Normal file
0
tests/data/empty.xml
Normal file
3
tests/data/multiline.xml
Normal file
3
tests/data/multiline.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<node1 />
|
||||
<node2 />
|
||||
<node3 />
|
BIN
tests/data/utftest_utf16_be.xml
Normal file
BIN
tests/data/utftest_utf16_be.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_be_bom.xml
Normal file
BIN
tests/data/utftest_utf16_be_bom.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_be_clean.xml
Normal file
BIN
tests/data/utftest_utf16_be_clean.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_be_nodecl.xml
Normal file
BIN
tests/data/utftest_utf16_be_nodecl.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_le.xml
Normal file
BIN
tests/data/utftest_utf16_le.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_le_bom.xml
Normal file
BIN
tests/data/utftest_utf16_le_bom.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_le_clean.xml
Normal file
BIN
tests/data/utftest_utf16_le_clean.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf16_le_nodecl.xml
Normal file
BIN
tests/data/utftest_utf16_le_nodecl.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_be.xml
Normal file
BIN
tests/data/utftest_utf32_be.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_be_bom.xml
Normal file
BIN
tests/data/utftest_utf32_be_bom.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_be_clean.xml
Normal file
BIN
tests/data/utftest_utf32_be_clean.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_be_nodecl.xml
Normal file
BIN
tests/data/utftest_utf32_be_nodecl.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_le.xml
Normal file
BIN
tests/data/utftest_utf32_le.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_le_bom.xml
Normal file
BIN
tests/data/utftest_utf32_le_bom.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_le_clean.xml
Normal file
BIN
tests/data/utftest_utf32_le_clean.xml
Normal file
Binary file not shown.
BIN
tests/data/utftest_utf32_le_nodecl.xml
Normal file
BIN
tests/data/utftest_utf32_le_nodecl.xml
Normal file
Binary file not shown.
87
tests/data/utftest_utf8.xml
Normal file
87
tests/data/utftest_utf8.xml
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE 週報 SYSTEM "weekly-utf-8.dtd">
|
||||
<!-- 週報サンプル -->
|
||||
<週報>
|
||||
<English name="name" value="value">The world has many languages</English>
|
||||
<Russian name="название(имя)" value="ценность">Мир имеет много языков</Russian>
|
||||
<Spanish name="el nombre" value="el valor">el mundo tiene muchos idiomas</Spanish>
|
||||
<SimplifiedChinese name="名字" value="价值">世界有很多语言</SimplifiedChinese>
|
||||
<Русский название="name" ценность="value"><имеет></Русский>
|
||||
<汉语 名字="name" 价值="value">世界有很多语言𤭢</汉语>
|
||||
<Heavy>"Mëtæl!"</Heavy>
|
||||
<ä>Umlaut Element</ä>
|
||||
|
||||
<年月週>
|
||||
<年度>1997</年度>
|
||||
<月度>1</月度>
|
||||
<週>1</週>
|
||||
</年月週>
|
||||
|
||||
<氏名>
|
||||
<氏>山田</氏>
|
||||
<名>太郎</名>
|
||||
</氏名>
|
||||
|
||||
<業務報告リスト>
|
||||
<業務報告>
|
||||
<業務名>XMLエディターの作成</業務名>
|
||||
<業務コード>X3355-23</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>1600</見積もり工数>
|
||||
<実績工数>320</実績工数>
|
||||
<当月見積もり工数>160</当月見積もり工数>
|
||||
<当月実績工数>24</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</実施事項>
|
||||
<実施事項>
|
||||
<P>競合他社製品の機能調査</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>特になし</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>XMLとは何かわからない。</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
|
||||
<業務報告>
|
||||
<業務名>検索エンジンの開発</業務名>
|
||||
<業務コード>S8821-76</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>120</見積もり工数>
|
||||
<実績工数>6</実績工数>
|
||||
<当月見積もり工数>32</当月見積もり工数>
|
||||
<当月実績工数>2</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P><A href="http://www.goo.ne.jp">goo</A>の機能を調べてみる</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>更に、どういう検索エンジンがあるか調査する</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>開発をするのはめんどうなので、Yahoo!を買収して下さい。</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>検索エンジンで車を走らせることができない。(要調査)</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
</業務報告リスト>
|
||||
</週報>
|
87
tests/data/utftest_utf8_bom.xml
Normal file
87
tests/data/utftest_utf8_bom.xml
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE 週報 SYSTEM "weekly-utf-8.dtd">
|
||||
<!-- 週報サンプル -->
|
||||
<週報>
|
||||
<English name="name" value="value">The world has many languages</English>
|
||||
<Russian name="название(имя)" value="ценность">Мир имеет много языков</Russian>
|
||||
<Spanish name="el nombre" value="el valor">el mundo tiene muchos idiomas</Spanish>
|
||||
<SimplifiedChinese name="名字" value="价值">世界有很多语言</SimplifiedChinese>
|
||||
<Русский название="name" ценность="value"><имеет></Русский>
|
||||
<汉语 名字="name" 价值="value">世界有很多语言𤭢</汉语>
|
||||
<Heavy>"Mëtæl!"</Heavy>
|
||||
<ä>Umlaut Element</ä>
|
||||
|
||||
<年月週>
|
||||
<年度>1997</年度>
|
||||
<月度>1</月度>
|
||||
<週>1</週>
|
||||
</年月週>
|
||||
|
||||
<氏名>
|
||||
<氏>山田</氏>
|
||||
<名>太郎</名>
|
||||
</氏名>
|
||||
|
||||
<業務報告リスト>
|
||||
<業務報告>
|
||||
<業務名>XMLエディターの作成</業務名>
|
||||
<業務コード>X3355-23</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>1600</見積もり工数>
|
||||
<実績工数>320</実績工数>
|
||||
<当月見積もり工数>160</当月見積もり工数>
|
||||
<当月実績工数>24</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</実施事項>
|
||||
<実施事項>
|
||||
<P>競合他社製品の機能調査</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>特になし</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>XMLとは何かわからない。</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
|
||||
<業務報告>
|
||||
<業務名>検索エンジンの開発</業務名>
|
||||
<業務コード>S8821-76</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>120</見積もり工数>
|
||||
<実績工数>6</実績工数>
|
||||
<当月見積もり工数>32</当月見積もり工数>
|
||||
<当月実績工数>2</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P><A href="http://www.goo.ne.jp">goo</A>の機能を調べてみる</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>更に、どういう検索エンジンがあるか調査する</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>開発をするのはめんどうなので、Yahoo!を買収して下さい。</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>検索エンジンで車を走らせることができない。(要調査)</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
</業務報告リスト>
|
||||
</週報>
|
84
tests/data/utftest_utf8_clean.xml
Normal file
84
tests/data/utftest_utf8_clean.xml
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0"?><!-- 週報サンプル --><週報>
|
||||
<English name="name" value="value">The world has many languages</English>
|
||||
<Russian name="название(имя)" value="ценность">Мир имеет много языков</Russian>
|
||||
<Spanish name="el nombre" value="el valor">el mundo tiene muchos idiomas</Spanish>
|
||||
<SimplifiedChinese name="名字" value="价值">世界有很多语言</SimplifiedChinese>
|
||||
<Русский название="name" ценность="value"><имеет></Русский>
|
||||
<汉语 名字="name" 价值="value">世界有很多语言𤭢</汉语>
|
||||
<Heavy>quot;Mëtæl!quot;</Heavy>
|
||||
<ä>Umlaut Element</ä>
|
||||
|
||||
<年月週>
|
||||
<年度>1997</年度>
|
||||
<月度>1</月度>
|
||||
<週>1</週>
|
||||
</年月週>
|
||||
|
||||
<氏名>
|
||||
<氏>山田</氏>
|
||||
<名>太郎</名>
|
||||
</氏名>
|
||||
|
||||
<業務報告リスト>
|
||||
<業務報告>
|
||||
<業務名>XMLエディターの作成</業務名>
|
||||
<業務コード>X3355-23</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>1600</見積もり工数>
|
||||
<実績工数>320</実績工数>
|
||||
<当月見積もり工数>160</当月見積もり工数>
|
||||
<当月実績工数>24</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</実施事項>
|
||||
<実施事項>
|
||||
<P>競合他社製品の機能調査</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>特になし</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>XMLとは何かわからない。</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
|
||||
<業務報告>
|
||||
<業務名>検索エンジンの開発</業務名>
|
||||
<業務コード>S8821-76</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>120</見積もり工数>
|
||||
<実績工数>6</実績工数>
|
||||
<当月見積もり工数>32</当月見積もり工数>
|
||||
<当月実績工数>2</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P><A href="http://www.goo.ne.jp">goo</A>の機能を調べてみる</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>更に、どういう検索エンジンがあるか調査する</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>開発をするのはめんどうなので、Yahoo!を買収して下さい。</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>検索エンジンで車を走らせることができない。(要調査)</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
</業務報告リスト>
|
||||
</週報>
|
86
tests/data/utftest_utf8_nodecl.xml
Normal file
86
tests/data/utftest_utf8_nodecl.xml
Normal file
|
@ -0,0 +1,86 @@
|
|||
<!DOCTYPE 週報 SYSTEM "weekly-utf-8.dtd">
|
||||
<!-- 週報サンプル -->
|
||||
<週報>
|
||||
<English name="name" value="value">The world has many languages</English>
|
||||
<Russian name="название(имя)" value="ценность">Мир имеет много языков</Russian>
|
||||
<Spanish name="el nombre" value="el valor">el mundo tiene muchos idiomas</Spanish>
|
||||
<SimplifiedChinese name="名字" value="价值">世界有很多语言</SimplifiedChinese>
|
||||
<Русский название="name" ценность="value"><имеет></Русский>
|
||||
<汉语 名字="name" 价值="value">世界有很多语言𤭢</汉语>
|
||||
<Heavy>"Mëtæl!"</Heavy>
|
||||
<ä>Umlaut Element</ä>
|
||||
|
||||
<年月週>
|
||||
<年度>1997</年度>
|
||||
<月度>1</月度>
|
||||
<週>1</週>
|
||||
</年月週>
|
||||
|
||||
<氏名>
|
||||
<氏>山田</氏>
|
||||
<名>太郎</名>
|
||||
</氏名>
|
||||
|
||||
<業務報告リスト>
|
||||
<業務報告>
|
||||
<業務名>XMLエディターの作成</業務名>
|
||||
<業務コード>X3355-23</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>1600</見積もり工数>
|
||||
<実績工数>320</実績工数>
|
||||
<当月見積もり工数>160</当月見積もり工数>
|
||||
<当月実績工数>24</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>XMLエディターの基本仕様の作成</P>
|
||||
</実施事項>
|
||||
<実施事項>
|
||||
<P>競合他社製品の機能調査</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>特になし</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>XMLとは何かわからない。</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
|
||||
<業務報告>
|
||||
<業務名>検索エンジンの開発</業務名>
|
||||
<業務コード>S8821-76</業務コード>
|
||||
<工数管理>
|
||||
<見積もり工数>120</見積もり工数>
|
||||
<実績工数>6</実績工数>
|
||||
<当月見積もり工数>32</当月見積もり工数>
|
||||
<当月実績工数>2</当月実績工数>
|
||||
</工数管理>
|
||||
<予定項目リスト>
|
||||
<予定項目>
|
||||
<P><A href="http://www.goo.ne.jp">goo</A>の機能を調べてみる</P>
|
||||
</予定項目>
|
||||
</予定項目リスト>
|
||||
<実施事項リスト>
|
||||
<実施事項>
|
||||
<P>更に、どういう検索エンジンがあるか調査する</P>
|
||||
</実施事項>
|
||||
</実施事項リスト>
|
||||
<上長への要請事項リスト>
|
||||
<上長への要請事項>
|
||||
<P>開発をするのはめんどうなので、Yahoo!を買収して下さい。</P>
|
||||
</上長への要請事項>
|
||||
</上長への要請事項リスト>
|
||||
<問題点対策>
|
||||
<P>検索エンジンで車を走らせることができない。(要調査)</P>
|
||||
</問題点対策>
|
||||
</業務報告>
|
||||
</業務報告リスト>
|
||||
</週報>
|
|
@ -49,7 +49,12 @@ template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
|
|||
T null = T();
|
||||
|
||||
// obj1 < obj2 (we use operator<, but there is no other choice
|
||||
if (obj1 > obj2) std::swap(obj1, obj2);
|
||||
if (obj1 > obj2)
|
||||
{
|
||||
T temp = obj1;
|
||||
obj1 = obj2;
|
||||
obj2 = temp;
|
||||
}
|
||||
|
||||
// operator<
|
||||
CHECK(null < obj1);
|
||||
|
|
|
@ -1,33 +1,26 @@
|
|||
#include "test.hpp"
|
||||
#include "allocator.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <float.h>
|
||||
|
||||
test_runner* test_runner::_tests = 0;
|
||||
size_t test_runner::_memory_fail_threshold = 0;
|
||||
jmp_buf test_runner::_failure;
|
||||
jmp_buf test_runner::_failure_buffer;
|
||||
const char* test_runner::_failure_message;
|
||||
|
||||
static size_t g_memory_total_size = 0;
|
||||
|
||||
#ifdef __linux
|
||||
size_t _msize(void* ptr)
|
||||
{
|
||||
return malloc_usable_size(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void* custom_allocate(size_t size)
|
||||
{
|
||||
if (test_runner::_memory_fail_threshold > 0 && test_runner::_memory_fail_threshold < size)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
void* ptr = malloc(size);
|
||||
void* ptr = memory_allocate(size);
|
||||
|
||||
g_memory_total_size += _msize(ptr);
|
||||
g_memory_total_size += memory_size(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
@ -37,9 +30,9 @@ static void custom_deallocate(void* ptr)
|
|||
{
|
||||
if (ptr)
|
||||
{
|
||||
g_memory_total_size -= _msize(ptr);
|
||||
g_memory_total_size -= memory_size(ptr);
|
||||
|
||||
free(ptr);
|
||||
memory_deallocate(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +41,7 @@ static void replace_memory_management()
|
|||
// create some document to touch original functions
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
doc.append_child().set_name("node");
|
||||
doc.append_child().set_name(STR("node"));
|
||||
}
|
||||
|
||||
// replace functions
|
||||
|
@ -77,7 +70,7 @@ static bool run_test(test_runner* test)
|
|||
# pragma warning(disable: 4611) // interaction between _setjmp and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
volatile int result = setjmp(test_runner::_failure);
|
||||
volatile int result = setjmp(test_runner::_failure_buffer);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
|
@ -85,13 +78,17 @@ static bool run_test(test_runner* test)
|
|||
|
||||
if (result)
|
||||
{
|
||||
printf("Test %s failed: %s\n", test->_name, (const char*)(intptr_t)result);
|
||||
printf("Test %s failed: %s\n", test->_name, test_runner::_failure_message);
|
||||
return false;
|
||||
}
|
||||
|
||||
test->run();
|
||||
|
||||
if (g_memory_total_size != 0) longjmp(test_runner::_failure, (int)(intptr_t)"Memory leaks found");
|
||||
if (g_memory_total_size != 0)
|
||||
{
|
||||
printf("Test %s failed: memory leaks found (%u bytes)\n", test->_name, (unsigned int)g_memory_total_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
|
|
134
tests/test.cpp
Normal file
134
tests/test.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include "test.hpp"
|
||||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
bool test_string_equal(const pugi::char_t* lhs, const pugi::char_t* rhs)
|
||||
{
|
||||
return (!lhs || !rhs) ? lhs == rhs : pugi::impl::strequal(lhs, rhs);
|
||||
}
|
||||
|
||||
bool test_node(const pugi::xml_node& node, const pugi::char_t* contents, const pugi::char_t* indent, unsigned int flags)
|
||||
{
|
||||
xml_writer_string writer;
|
||||
|
||||
node.print(writer, indent, flags, get_native_encoding());
|
||||
|
||||
return writer.as_string() == contents;
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
bool test_xpath_string(const pugi::xml_node& node, const pugi::char_t* query, const pugi::char_t* expected)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
return q.evaluate_string(node) == expected;
|
||||
}
|
||||
|
||||
bool test_xpath_boolean(const pugi::xml_node& node, const pugi::char_t* query, bool expected)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
return q.evaluate_boolean(node) == expected;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
bool test_xpath_number(const pugi::xml_node& node, const pugi::char_t* query, double expected)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
double value = q.evaluate_number(node);
|
||||
double absolute_error = fabs(value - expected);
|
||||
|
||||
const double tolerance = 1e-15f;
|
||||
return absolute_error < tolerance || absolute_error < fabs(expected) * tolerance;
|
||||
}
|
||||
|
||||
bool test_xpath_number_nan(const pugi::xml_node& node, const pugi::char_t* query)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
double r = q.evaluate_number(node);
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
return _isnan(r) != 0;
|
||||
#else
|
||||
return r != r;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_xpath_fail_compile(const pugi::char_t* query)
|
||||
{
|
||||
try
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
return false;
|
||||
}
|
||||
catch (const pugi::xpath_exception&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void xpath_node_set_tester::check(bool condition)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
test_runner::_failure_message = message;
|
||||
longjmp(test_runner::_failure_buffer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
xpath_node_set_tester::xpath_node_set_tester(const pugi::xml_node& node, const pugi::char_t* query, const char* message): last(0), message(message)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
result = q.evaluate_node_set(node);
|
||||
}
|
||||
|
||||
xpath_node_set_tester::xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message): last(0), message(message)
|
||||
{
|
||||
result = set;
|
||||
}
|
||||
|
||||
xpath_node_set_tester::~xpath_node_set_tester()
|
||||
{
|
||||
// check that we processed everything
|
||||
check(last == result.size());
|
||||
}
|
||||
|
||||
xpath_node_set_tester& xpath_node_set_tester::operator%(unsigned int expected)
|
||||
{
|
||||
// check element count
|
||||
check(last < result.size());
|
||||
|
||||
// check document order
|
||||
pugi::xpath_node node = result.begin()[last];
|
||||
unsigned int order = node.attribute() ? node.attribute().document_order() : node.node().document_order();
|
||||
|
||||
check(order == expected);
|
||||
|
||||
// continue to the next element
|
||||
last++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool is_little_endian()
|
||||
{
|
||||
unsigned int ui = 1;
|
||||
return *reinterpret_cast<char*>(&ui) == 1;
|
||||
}
|
||||
|
||||
pugi::encoding_t get_native_encoding()
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
return pugi::encoding_wchar;
|
||||
#else
|
||||
return pugi::encoding_utf8;
|
||||
#endif
|
||||
}
|
179
tests/test.hpp
179
tests/test.hpp
|
@ -3,21 +3,8 @@
|
|||
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER==1200) || defined(__DMC__)
|
||||
typedef int intptr_t;
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#if defined(__MWERKS__) || defined(__BORLANDC__)
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
struct test_runner
|
||||
{
|
||||
test_runner(const char* name)
|
||||
|
@ -36,84 +23,25 @@ struct test_runner
|
|||
|
||||
static test_runner* _tests;
|
||||
static size_t _memory_fail_threshold;
|
||||
static jmp_buf _failure;
|
||||
static jmp_buf _failure_buffer;
|
||||
static const char* _failure_message;
|
||||
};
|
||||
|
||||
inline bool test_string_equal(const char* lhs, const char* rhs)
|
||||
{
|
||||
return (!lhs || !rhs) ? lhs == rhs : strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
bool test_string_equal(const pugi::char_t* lhs, const pugi::char_t* rhs);
|
||||
|
||||
template <typename Node> inline bool test_node_name_value(const Node& node, const char* name, const char* value)
|
||||
template <typename Node> inline bool test_node_name_value(const Node& node, const pugi::char_t* name, const pugi::char_t* value)
|
||||
{
|
||||
return test_string_equal(node.name(), name) && test_string_equal(node.value(), value);
|
||||
}
|
||||
|
||||
struct xml_writer_string: public pugi::xml_writer
|
||||
{
|
||||
std::string result;
|
||||
|
||||
virtual void write(const void* data, size_t size)
|
||||
{
|
||||
result += std::string(static_cast<const char*>(data), size);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool test_node(const pugi::xml_node& node, const char* contents, const char* indent, unsigned int flags)
|
||||
{
|
||||
xml_writer_string writer;
|
||||
node.print(writer, indent, flags);
|
||||
|
||||
return writer.result == contents;
|
||||
}
|
||||
bool test_node(const pugi::xml_node& node, const pugi::char_t* contents, const pugi::char_t* indent, unsigned int flags);
|
||||
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
inline bool test_xpath_string(const pugi::xml_node& node, const char* query, const char* expected)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
return q.evaluate_string(node) == expected;
|
||||
}
|
||||
|
||||
inline bool test_xpath_boolean(const pugi::xml_node& node, const char* query, bool expected)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
return q.evaluate_boolean(node) == expected;
|
||||
}
|
||||
|
||||
inline bool test_xpath_number(const pugi::xml_node& node, const char* query, double expected)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
return fabs(q.evaluate_number(node) - expected) < 1e-16f;
|
||||
}
|
||||
|
||||
inline bool test_xpath_number_nan(const pugi::xml_node& node, const char* query)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
|
||||
double r = q.evaluate_number(node);
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
return _isnan(r) != 0;
|
||||
#else
|
||||
return r != r;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool test_xpath_fail_compile(const char* query)
|
||||
{
|
||||
try
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
return false;
|
||||
}
|
||||
catch (const pugi::xpath_exception&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool test_xpath_string(const pugi::xml_node& node, const pugi::char_t* query, const pugi::char_t* expected);
|
||||
bool test_xpath_boolean(const pugi::xml_node& node, const pugi::char_t* query, bool expected);
|
||||
bool test_xpath_number(const pugi::xml_node& node, const pugi::char_t* query, double expected);
|
||||
bool test_xpath_number_nan(const pugi::xml_node& node, const pugi::char_t* query);
|
||||
bool test_xpath_fail_compile(const pugi::char_t* query);
|
||||
|
||||
struct xpath_node_set_tester
|
||||
{
|
||||
|
@ -121,44 +49,13 @@ struct xpath_node_set_tester
|
|||
unsigned int last;
|
||||
const char* message;
|
||||
|
||||
void check(bool condition)
|
||||
{
|
||||
if (!condition) longjmp(test_runner::_failure, (int)(intptr_t)message);
|
||||
}
|
||||
void check(bool condition);
|
||||
|
||||
xpath_node_set_tester(const pugi::xml_node& node, const char* query, const char* message): last(0), message(message)
|
||||
{
|
||||
pugi::xpath_query q(query);
|
||||
result = q.evaluate_node_set(node);
|
||||
}
|
||||
xpath_node_set_tester(const pugi::xml_node& node, const pugi::char_t* query, const char* message);
|
||||
xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message);
|
||||
~xpath_node_set_tester();
|
||||
|
||||
xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message): last(0), message(message)
|
||||
{
|
||||
result = set;
|
||||
}
|
||||
|
||||
~xpath_node_set_tester()
|
||||
{
|
||||
// check that we processed everything
|
||||
check(last == result.size());
|
||||
}
|
||||
|
||||
xpath_node_set_tester& operator%(unsigned int expected)
|
||||
{
|
||||
// check element count
|
||||
check(last < result.size());
|
||||
|
||||
// check document order
|
||||
pugi::xpath_node node = result.begin()[last];
|
||||
unsigned int order = node.attribute() ? node.attribute().document_order() : node.node().document_order();
|
||||
|
||||
check(order == expected);
|
||||
|
||||
// continue to the next element
|
||||
last++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
xpath_node_set_tester& operator%(unsigned int expected);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -191,7 +88,7 @@ struct dummy_fixture {};
|
|||
\
|
||||
test_fixture_##name() \
|
||||
{ \
|
||||
CHECK(doc.load(xml, flags)); \
|
||||
CHECK(doc.load(PUGIXML_TEXT(xml), flags)); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
|
@ -205,28 +102,42 @@ struct dummy_fixture {};
|
|||
|
||||
#define CHECK_JOIN(text, file, line) text file #line
|
||||
#define CHECK_JOIN2(text, file, line) CHECK_JOIN(text, file, line)
|
||||
#define CHECK_TEXT(condition, text) if (condition) ; else longjmp(test_runner::_failure, (int)(intptr_t)(CHECK_JOIN2(text, " at "__FILE__ ":", __LINE__)))
|
||||
#define CHECK_TEXT(condition, text) if (condition) ; else test_runner::_failure_message = CHECK_JOIN2(text, " at "__FILE__ ":", __LINE__), longjmp(test_runner::_failure_buffer, 1)
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER == 1200) || defined(__MWERKS__)
|
||||
# define STR(value) "??" // MSVC 6.0 and CodeWarrior have troubles stringizing stuff with strings w/escaping inside
|
||||
# define STRINGIZE(value) "??" // MSVC 6.0 and CodeWarrior have troubles stringizing stuff with strings w/escaping inside
|
||||
#else
|
||||
# define STR(value) #value
|
||||
# define STRINGIZE(value) #value
|
||||
#endif
|
||||
|
||||
#define CHECK(condition) CHECK_TEXT(condition, STR(condition) " is false")
|
||||
#define CHECK_STRING(value, expected) CHECK_TEXT(test_string_equal(value, expected), STR(value) " is not equal to " STR(expected))
|
||||
#define CHECK_DOUBLE(value, expected) CHECK_TEXT(fabs(value - expected) < 1e-6, STR(value) " is not equal to " STR(expected))
|
||||
#define CHECK_NAME_VALUE(node, name, value) CHECK_TEXT(test_node_name_value(node, name, value), STR(node) " name/value do not match " STR(name) " and " STR(value))
|
||||
#define CHECK_NODE_EX(node, expected, indent, flags) CHECK_TEXT(test_node(node, expected, indent, flags), STR(node) " contents does not match " STR(expected))
|
||||
#define CHECK_NODE(node, expected) CHECK_NODE_EX(node, expected, "", pugi::format_raw)
|
||||
#define CHECK(condition) CHECK_TEXT(condition, STRINGIZE(condition) " is false")
|
||||
#define CHECK_STRING(value, expected) CHECK_TEXT(test_string_equal(value, expected), STRINGIZE(value) " is not equal to " STRINGIZE(expected))
|
||||
#define CHECK_DOUBLE(value, expected) CHECK_TEXT((value > expected ? value - expected : expected - value) < 1e-6, STRINGIZE(value) " is not equal to " STRINGIZE(expected))
|
||||
#define CHECK_NAME_VALUE(node, name, value) CHECK_TEXT(test_node_name_value(node, name, value), STRINGIZE(node) " name/value do not match " STRINGIZE(name) " and " STRINGIZE(value))
|
||||
#define CHECK_NODE_EX(node, expected, indent, flags) CHECK_TEXT(test_node(node, expected, indent, flags), STRINGIZE(node) " contents does not match " STRINGIZE(expected))
|
||||
#define CHECK_NODE(node, expected) CHECK_NODE_EX(node, expected, PUGIXML_TEXT(""), pugi::format_raw)
|
||||
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
#define CHECK_XPATH_STRING(node, query, expected) CHECK_TEXT(test_xpath_string(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
|
||||
#define CHECK_XPATH_BOOLEAN(node, query, expected) CHECK_TEXT(test_xpath_boolean(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
|
||||
#define CHECK_XPATH_NUMBER(node, query, expected) CHECK_TEXT(test_xpath_number(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
|
||||
#define CHECK_XPATH_NUMBER_NAN(node, query) CHECK_TEXT(test_xpath_number_nan(node, query), STR(query) " does not evaluate to NaN in context " STR(node))
|
||||
#define CHECK_XPATH_FAIL(query) CHECK_TEXT(test_xpath_fail_compile(query), STR(query) " should not compile")
|
||||
#define CHECK_XPATH_NODESET(node, query) xpath_node_set_tester(node, query, CHECK_JOIN2(STR(query) " does not evaluate to expected set in context " STR(node), " at "__FILE__ ":", __LINE__))
|
||||
#define CHECK_XPATH_STRING(node, query, expected) CHECK_TEXT(test_xpath_string(node, query, expected), STRINGIZE(query) " does not evaluate to " STRINGIZE(expected) " in context " STRINGIZE(node))
|
||||
#define CHECK_XPATH_BOOLEAN(node, query, expected) CHECK_TEXT(test_xpath_boolean(node, query, expected), STRINGIZE(query) " does not evaluate to " STRINGIZE(expected) " in context " STRINGIZE(node))
|
||||
#define CHECK_XPATH_NUMBER(node, query, expected) CHECK_TEXT(test_xpath_number(node, query, expected), STRINGIZE(query) " does not evaluate to " STRINGIZE(expected) " in context " STRINGIZE(node))
|
||||
#define CHECK_XPATH_NUMBER_NAN(node, query) CHECK_TEXT(test_xpath_number_nan(node, query), STRINGIZE(query) " does not evaluate to NaN in context " STRINGIZE(node))
|
||||
#define CHECK_XPATH_FAIL(query) CHECK_TEXT(test_xpath_fail_compile(query), STRINGIZE(query) " should not compile")
|
||||
#define CHECK_XPATH_NODESET(node, query) xpath_node_set_tester(node, query, CHECK_JOIN2(STRINGIZE(query) " does not evaluate to expected set in context " STRINGIZE(node), " at "__FILE__ ":", __LINE__))
|
||||
#endif
|
||||
|
||||
#define STR(text) PUGIXML_TEXT(text)
|
||||
|
||||
#ifdef __DMC__
|
||||
#define U_LITERALS // DMC does not understand \x01234 (it parses first three digits), but understands \u01234
|
||||
#endif
|
||||
|
||||
inline wchar_t wchar_cast(unsigned int value)
|
||||
{
|
||||
return static_cast<wchar_t>(value); // to avoid C4310 on MSVC
|
||||
}
|
||||
|
||||
bool is_little_endian();
|
||||
pugi::encoding_t get_native_encoding();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
#include <string.h> // because Borland's STL is braindead, we have to include <string.h> _before_ <string> in order to get memcpy
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4996)
|
||||
|
@ -13,8 +19,8 @@
|
|||
TEST(document_create)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
doc.append_child().set_name("node");
|
||||
CHECK_NODE(doc, "<node />");
|
||||
doc.append_child().set_name(STR("node"));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
|
@ -24,7 +30,29 @@ TEST(document_load_stream)
|
|||
|
||||
std::istringstream iss("<node/>");
|
||||
CHECK(doc.load(iss));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_load_stream_offset)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
||||
std::istringstream iss("<foobar> <node/>");
|
||||
|
||||
std::string s;
|
||||
iss >> s;
|
||||
|
||||
CHECK(doc.load(iss));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_load_stream_text)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
||||
std::ifstream iss("tests/data/multiline.xml");
|
||||
CHECK(doc.load(iss));
|
||||
CHECK_NODE(doc, STR("<node1 /><node2 /><node3 />"));
|
||||
}
|
||||
|
||||
TEST(document_load_stream_error)
|
||||
|
@ -39,21 +67,27 @@ TEST(document_load_stream_error)
|
|||
CHECK(doc.load(fs2).status == status_io_error);
|
||||
#endif
|
||||
|
||||
std::ifstream fs3("nul");
|
||||
CHECK(doc.load(fs3).status == status_io_error);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
std::istringstream iss("<node/>");
|
||||
CHECK(doc.load(iss).status == status_out_of_memory);
|
||||
}
|
||||
|
||||
TEST(document_load_stream_wide)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
||||
std::basic_istringstream<wchar_t> iss(L"<node/>");
|
||||
CHECK(doc.load(iss));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(document_load_string)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
||||
CHECK(doc.load("<node/>"));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK(doc.load(STR("<node/>")));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_load_file)
|
||||
|
@ -61,7 +95,15 @@ TEST(document_load_file)
|
|||
pugi::xml_document doc;
|
||||
|
||||
CHECK(doc.load_file("tests/data/small.xml"));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_load_file_empty)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
||||
CHECK(doc.load_file("tests/data/empty.xml"));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(document_load_file_large)
|
||||
|
@ -70,10 +112,10 @@ TEST(document_load_file_large)
|
|||
|
||||
CHECK(doc.load_file("tests/data/large.xml"));
|
||||
|
||||
std::string str;
|
||||
str += "<node>";
|
||||
for (int i = 0; i < 10000; ++i) str += "<node />";
|
||||
str += "</node>";
|
||||
std::basic_string<pugi::char_t> str;
|
||||
str += STR("<node>");
|
||||
for (int i = 0; i < 10000; ++i) str += STR("<node />");
|
||||
str += STR("</node>");
|
||||
|
||||
CHECK_NODE(doc, str.c_str());
|
||||
}
|
||||
|
@ -84,14 +126,10 @@ TEST(document_load_file_error)
|
|||
|
||||
CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found);
|
||||
|
||||
#ifdef __linux
|
||||
CHECK(doc.load_file("/dev/null").status == status_io_error);
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#ifndef __DMC__ // Digital Mars CRT does not like 'con' pseudo-file
|
||||
CHECK(doc.load_file("con").status == status_io_error);
|
||||
#endif
|
||||
|
||||
CHECK(doc.load_file("nul").status == status_io_error);
|
||||
#endif
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
@ -102,27 +140,57 @@ TEST_XML(document_save, "<node/>")
|
|||
{
|
||||
xml_writer_string writer;
|
||||
|
||||
doc.save(writer, "", pugi::format_no_declaration | pugi::format_raw);
|
||||
doc.save(writer, STR(""), pugi::format_no_declaration | pugi::format_raw, get_native_encoding());
|
||||
|
||||
CHECK(writer.result == "<node />");
|
||||
CHECK(writer.as_string() == STR("<node />"));
|
||||
}
|
||||
|
||||
TEST_XML(document_save_bom, "<node/>")
|
||||
#ifndef PUGIXML_NO_STL
|
||||
TEST_XML(document_save_stream, "<node/>")
|
||||
{
|
||||
xml_writer_string writer;
|
||||
std::ostringstream oss;
|
||||
|
||||
doc.save(writer, "", pugi::format_no_declaration | pugi::format_raw | pugi::format_write_bom_utf8);
|
||||
doc.save(oss, STR(""), pugi::format_no_declaration | pugi::format_raw);
|
||||
|
||||
CHECK(writer.result == "\xef\xbb\xbf<node />");
|
||||
CHECK(oss.str() == "<node />");
|
||||
}
|
||||
|
||||
TEST_XML(document_save_stream_wide, "<node/>")
|
||||
{
|
||||
std::basic_ostringstream<wchar_t> oss;
|
||||
|
||||
doc.save(oss, STR(""), pugi::format_no_declaration | pugi::format_raw);
|
||||
|
||||
CHECK(oss.str() == L"<node />");
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(document_save_bom, "<n/>")
|
||||
{
|
||||
unsigned int flags = format_no_declaration | format_raw | format_write_bom;
|
||||
|
||||
// specific encodings
|
||||
CHECK(test_save_narrow(doc, flags, encoding_utf8, "\xef\xbb\xbf<n />", 8));
|
||||
CHECK(test_save_narrow(doc, flags, encoding_utf16_be, "\xfe\xff\x00<\x00n\x00 \x00/\x00>", 12));
|
||||
CHECK(test_save_narrow(doc, flags, encoding_utf16_le, "\xff\xfe<\x00n\x00 \x00/\x00>\x00", 12));
|
||||
CHECK(test_save_narrow(doc, flags, encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00<\x00\x00\x00n\x00\x00\x00 \x00\x00\x00/\x00\x00\x00>", 24));
|
||||
CHECK(test_save_narrow(doc, flags, encoding_utf32_le, "\xff\xfe\x00\x00<\x00\x00\x00n\x00\x00\x00 \x00\x00\x00/\x00\x00\x00>\x00\x00\x00", 24));
|
||||
|
||||
// encodings synonyms
|
||||
CHECK(save_narrow(doc, flags, encoding_utf16) == save_narrow(doc, flags, (is_little_endian() ? encoding_utf16_le : encoding_utf16_be)));
|
||||
CHECK(save_narrow(doc, flags, encoding_utf32) == save_narrow(doc, flags, (is_little_endian() ? encoding_utf32_le : encoding_utf32_be)));
|
||||
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
CHECK(save_narrow(doc, flags, encoding_wchar) == save_narrow(doc, flags, (wcharsize == 2 ? encoding_utf16 : encoding_utf32)));
|
||||
}
|
||||
|
||||
TEST_XML(document_save_declaration, "<node/>")
|
||||
{
|
||||
xml_writer_string writer;
|
||||
|
||||
doc.save(writer);
|
||||
doc.save(writer, STR(""), pugi::format_default, get_native_encoding());
|
||||
|
||||
CHECK(writer.result == "<?xml version=\"1.0\"?>\n<node />\n");
|
||||
CHECK(writer.as_string() == STR("<?xml version=\"1.0\"?>\n<node />\n"));
|
||||
}
|
||||
|
||||
TEST_XML(document_save_file, "<node/>")
|
||||
|
@ -130,34 +198,46 @@ TEST_XML(document_save_file, "<node/>")
|
|||
CHECK(doc.save_file("tests/data/output.xml"));
|
||||
|
||||
CHECK(doc.load_file("tests/data/output.xml", pugi::parse_default | pugi::parse_declaration));
|
||||
CHECK_NODE(doc, "<?xml version=\"1.0\"?><node />");
|
||||
CHECK_NODE(doc, STR("<?xml version=\"1.0\"?><node />"));
|
||||
|
||||
unlink("tests/data/output.xml");
|
||||
}
|
||||
|
||||
TEST(document_parse)
|
||||
TEST(document_load_buffer)
|
||||
{
|
||||
char text[] = "<node/>";
|
||||
const pugi::char_t text[] = STR("<?xml?><node/>");
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
||||
CHECK(doc.parse(text));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK(doc.load_buffer(text, sizeof(text)));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_parse_transfer_ownership)
|
||||
TEST(document_load_buffer_inplace)
|
||||
{
|
||||
pugi::char_t text[] = STR("<?xml?><node/>");
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
||||
CHECK(doc.load_buffer_inplace(text, sizeof(text)));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_load_buffer_inplace_own)
|
||||
{
|
||||
allocation_function alloc = get_memory_allocation_function();
|
||||
|
||||
char* text = static_cast<char*>(alloc(strlen("<node/>") + 1));
|
||||
size_t size = strlen("<?xml?><node/>") * sizeof(pugi::char_t);
|
||||
|
||||
pugi::char_t* text = static_cast<pugi::char_t*>(alloc(size));
|
||||
CHECK(text);
|
||||
|
||||
strcpy(text, "<node/>");
|
||||
memcpy(text, STR("<?xml?><node/>"), size);
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
||||
CHECK(doc.parse(transfer_ownership_tag(), text));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK(doc.load_buffer_inplace_own(text, size));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(document_parse_result_bool)
|
||||
|
@ -189,3 +269,306 @@ TEST(document_parse_result_description)
|
|||
CHECK(result.description()[0] != 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(document_load_fail)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(!doc.load(STR("<foo><bar/>")));
|
||||
CHECK(doc.child(STR("foo")).child(STR("bar")));
|
||||
}
|
||||
|
||||
inline void check_utftest_document(const xml_document& doc)
|
||||
{
|
||||
// ascii text
|
||||
CHECK_STRING(doc.last_child().first_child().name(), STR("English"));
|
||||
|
||||
// check that we have parsed some non-ascii text
|
||||
CHECK((unsigned)doc.last_child().last_child().name()[0] >= 0x80);
|
||||
|
||||
// check magic string
|
||||
const pugi::char_t* v = doc.last_child().child(STR("Heavy")).previous_sibling().child_value();
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
CHECK(v[0] == 0x4e16 && v[1] == 0x754c && v[2] == 0x6709 && v[3] == 0x5f88 && v[4] == 0x591a && v[5] == 0x8bed && v[6] == 0x8a00);
|
||||
|
||||
// last character is a surrogate pair
|
||||
unsigned int v7 = v[7];
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
|
||||
CHECK(wcharsize == 2 ? (v[7] == 0xd852 && v[8] == 0xdf62) : (v7 == 0x24b62));
|
||||
#else
|
||||
// unicode string
|
||||
CHECK_STRING(v, "\xe4\xb8\x96\xe7\x95\x8c\xe6\x9c\x89\xe5\xbe\x88\xe5\xa4\x9a\xe8\xaf\xad\xe8\xa8\x80\xf0\xa4\xad\xa2");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(document_load_file_convert_auto)
|
||||
{
|
||||
const char* files[] =
|
||||
{
|
||||
"tests/data/utftest_utf16_be.xml",
|
||||
"tests/data/utftest_utf16_be_bom.xml",
|
||||
"tests/data/utftest_utf16_be_nodecl.xml",
|
||||
"tests/data/utftest_utf16_le.xml",
|
||||
"tests/data/utftest_utf16_le_bom.xml",
|
||||
"tests/data/utftest_utf16_le_nodecl.xml",
|
||||
"tests/data/utftest_utf32_be.xml",
|
||||
"tests/data/utftest_utf32_be_bom.xml",
|
||||
"tests/data/utftest_utf32_be_nodecl.xml",
|
||||
"tests/data/utftest_utf32_le.xml",
|
||||
"tests/data/utftest_utf32_le_bom.xml",
|
||||
"tests/data/utftest_utf32_le_nodecl.xml",
|
||||
"tests/data/utftest_utf8.xml",
|
||||
"tests/data/utftest_utf8_bom.xml",
|
||||
"tests/data/utftest_utf8_nodecl.xml"
|
||||
};
|
||||
|
||||
encoding_t encodings[] =
|
||||
{
|
||||
encoding_utf16_be, encoding_utf16_be, encoding_utf16_be,
|
||||
encoding_utf16_le, encoding_utf16_le, encoding_utf16_le,
|
||||
encoding_utf32_be, encoding_utf32_be, encoding_utf32_be,
|
||||
encoding_utf32_le, encoding_utf32_le, encoding_utf32_le,
|
||||
encoding_utf8, encoding_utf8, encoding_utf8
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_file(files[i]);
|
||||
|
||||
CHECK(res);
|
||||
CHECK(res.encoding == encodings[i]);
|
||||
check_utftest_document(doc);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(document_load_file_convert_specific)
|
||||
{
|
||||
const char* files[] =
|
||||
{
|
||||
"tests/data/utftest_utf16_be.xml",
|
||||
"tests/data/utftest_utf16_be_bom.xml",
|
||||
"tests/data/utftest_utf16_be_nodecl.xml",
|
||||
"tests/data/utftest_utf16_le.xml",
|
||||
"tests/data/utftest_utf16_le_bom.xml",
|
||||
"tests/data/utftest_utf16_le_nodecl.xml",
|
||||
"tests/data/utftest_utf32_be.xml",
|
||||
"tests/data/utftest_utf32_be_bom.xml",
|
||||
"tests/data/utftest_utf32_be_nodecl.xml",
|
||||
"tests/data/utftest_utf32_le.xml",
|
||||
"tests/data/utftest_utf32_le_bom.xml",
|
||||
"tests/data/utftest_utf32_le_nodecl.xml",
|
||||
"tests/data/utftest_utf8.xml",
|
||||
"tests/data/utftest_utf8_bom.xml",
|
||||
"tests/data/utftest_utf8_nodecl.xml"
|
||||
};
|
||||
|
||||
encoding_t encodings[] =
|
||||
{
|
||||
encoding_utf16_be, encoding_utf16_be, encoding_utf16_be,
|
||||
encoding_utf16_le, encoding_utf16_le, encoding_utf16_le,
|
||||
encoding_utf32_be, encoding_utf32_be, encoding_utf32_be,
|
||||
encoding_utf32_le, encoding_utf32_le, encoding_utf32_le,
|
||||
encoding_utf8, encoding_utf8, encoding_utf8
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
{
|
||||
for (unsigned int j = 0; j < sizeof(files) / sizeof(files[0]); ++j)
|
||||
{
|
||||
encoding_t encoding = encodings[j];
|
||||
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_file(files[i], parse_default, encoding);
|
||||
|
||||
if (encoding == encodings[i])
|
||||
{
|
||||
CHECK(res);
|
||||
CHECK(res.encoding == encoding);
|
||||
check_utftest_document(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// should not get past first tag
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(document_load_file_convert_native_endianness)
|
||||
{
|
||||
const char* files[2][6] =
|
||||
{
|
||||
{
|
||||
"tests/data/utftest_utf16_be.xml",
|
||||
"tests/data/utftest_utf16_be_bom.xml",
|
||||
"tests/data/utftest_utf16_be_nodecl.xml",
|
||||
"tests/data/utftest_utf32_be.xml",
|
||||
"tests/data/utftest_utf32_be_bom.xml",
|
||||
"tests/data/utftest_utf32_be_nodecl.xml",
|
||||
},
|
||||
{
|
||||
"tests/data/utftest_utf16_le.xml",
|
||||
"tests/data/utftest_utf16_le_bom.xml",
|
||||
"tests/data/utftest_utf16_le_nodecl.xml",
|
||||
"tests/data/utftest_utf32_le.xml",
|
||||
"tests/data/utftest_utf32_le_bom.xml",
|
||||
"tests/data/utftest_utf32_le_nodecl.xml",
|
||||
}
|
||||
};
|
||||
|
||||
encoding_t encodings[] =
|
||||
{
|
||||
encoding_utf16, encoding_utf16, encoding_utf16,
|
||||
encoding_utf32, encoding_utf32, encoding_utf32
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(files[0]) / sizeof(files[0][0]); ++i)
|
||||
{
|
||||
const char* right_file = files[is_little_endian()][i];
|
||||
const char* wrong_file = files[!is_little_endian()][i];
|
||||
|
||||
for (unsigned int j = 0; j < sizeof(encodings) / sizeof(encodings[0]); ++j)
|
||||
{
|
||||
encoding_t encoding = encodings[j];
|
||||
|
||||
// check file with right endianness
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_file(right_file, parse_default, encoding);
|
||||
|
||||
if (encoding == encodings[i])
|
||||
{
|
||||
CHECK(res);
|
||||
check_utftest_document(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// should not get past first tag
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
}
|
||||
|
||||
// check file with wrong endianness
|
||||
{
|
||||
xml_document doc;
|
||||
doc.load_file(wrong_file, parse_default, encoding);
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool load_file_in_memory(const char* path, char*& data, size_t& size)
|
||||
{
|
||||
FILE* file = fopen(path, "rb");
|
||||
if (!file) return false;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
size = (size_t)ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
data = new char[size];
|
||||
|
||||
CHECK(fread(data, 1, size, file) == size);
|
||||
fclose(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(document_contents_preserve)
|
||||
{
|
||||
struct file_t
|
||||
{
|
||||
const char* path;
|
||||
encoding_t encoding;
|
||||
|
||||
char* data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
file_t files[] =
|
||||
{
|
||||
{"tests/data/utftest_utf16_be_clean.xml", encoding_utf16_be, 0, 0},
|
||||
{"tests/data/utftest_utf16_le_clean.xml", encoding_utf16_le, 0, 0},
|
||||
{"tests/data/utftest_utf32_be_clean.xml", encoding_utf32_be, 0, 0},
|
||||
{"tests/data/utftest_utf32_le_clean.xml", encoding_utf32_le, 0, 0},
|
||||
{"tests/data/utftest_utf8_clean.xml", encoding_utf8, 0, 0}
|
||||
};
|
||||
|
||||
// load files in memory
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
{
|
||||
CHECK(load_file_in_memory(files[i].path, files[i].data, files[i].size));
|
||||
}
|
||||
|
||||
// convert each file to each format and compare bitwise
|
||||
for (unsigned int src = 0; src < sizeof(files) / sizeof(files[0]); ++src)
|
||||
{
|
||||
for (unsigned int dst = 0; dst < sizeof(files) / sizeof(files[0]); ++dst)
|
||||
{
|
||||
// parse into document (preserve comments, declaration and whitespace pcdata)
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(files[src].data, files[src].size, parse_default | parse_ws_pcdata | parse_declaration | parse_comments));
|
||||
|
||||
// compare saved document with the original (raw formatting, without extra declaration, write bom if it was in original file)
|
||||
CHECK(test_save_narrow(doc, format_raw | format_no_declaration | format_write_bom, files[dst].encoding, files[dst].data, files[dst].size));
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
for (unsigned int j = 0; j < sizeof(files) / sizeof(files[0]); ++j)
|
||||
{
|
||||
delete[] files[j].data;
|
||||
}
|
||||
}
|
||||
|
||||
static bool test_parse_fail(const void* buffer, size_t size, encoding_t encoding = encoding_utf8)
|
||||
{
|
||||
// copy buffer to heap (to enable out-of-bounds checks)
|
||||
void* temp = malloc(size);
|
||||
memcpy(temp, buffer, size);
|
||||
|
||||
// check that this parses without buffer overflows (yielding an error)
|
||||
xml_document doc;
|
||||
bool result = doc.load_buffer_inplace(temp, size, parse_default, encoding);
|
||||
|
||||
free(temp);
|
||||
|
||||
return !result;
|
||||
}
|
||||
|
||||
TEST(document_convert_invalid_utf8)
|
||||
{
|
||||
// invalid 1-byte input
|
||||
CHECK(test_parse_fail("<\xb0", 2));
|
||||
|
||||
// invalid 2-byte input
|
||||
CHECK(test_parse_fail("<\xc0", 2));
|
||||
CHECK(test_parse_fail("<\xd0", 2));
|
||||
|
||||
// invalid 3-byte input
|
||||
CHECK(test_parse_fail("<\xe2\x80", 3));
|
||||
CHECK(test_parse_fail("<\xe2", 2));
|
||||
|
||||
// invalid 4-byte input
|
||||
CHECK(test_parse_fail("<\xf2\x97\x98", 4));
|
||||
CHECK(test_parse_fail("<\xf2\x97", 3));
|
||||
CHECK(test_parse_fail("<\xf2", 2));
|
||||
|
||||
// invalid 5-byte input
|
||||
CHECK(test_parse_fail("<\xf8", 2));
|
||||
}
|
||||
|
||||
TEST(document_convert_invalid_utf16)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
CHECK(test_parse_fail("\x00<\xda\x1d", 4, encoding_utf16_be));
|
||||
CHECK(test_parse_fail("<\x00\x1d\xda", 4, encoding_utf16_le));
|
||||
|
||||
// check incorrect leading code
|
||||
CHECK(test_parse_fail("\x00<\xde\x24", 4, encoding_utf16_be));
|
||||
CHECK(test_parse_fail("<\x00\x24\xde", 4, encoding_utf16_le));
|
||||
}
|
||||
|
|
|
@ -1,158 +1,170 @@
|
|||
#include "common.hpp"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
TEST_XML(dom_attr_assign, "<node attr1='' attr2='' attr3='' attr4='' attr5=''/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
node.attribute("attr1") = "v1";
|
||||
xml_attribute() = "v1";
|
||||
node.attribute(STR("attr1")) = STR("v1");
|
||||
xml_attribute() = STR("v1");
|
||||
|
||||
node.attribute("attr2") = -2147483647 - 1;
|
||||
node.attribute(STR("attr2")) = -2147483647 - 1;
|
||||
xml_attribute() = -2147483647 - 1;
|
||||
|
||||
node.attribute("attr3") = 2147483647u;
|
||||
node.attribute(STR("attr3")) = 2147483647u;
|
||||
xml_attribute() = 2147483647;
|
||||
|
||||
node.attribute("attr4") = 0.5;
|
||||
node.attribute(STR("attr4")) = 0.5;
|
||||
xml_attribute() = 0.5;
|
||||
|
||||
node.attribute("attr5") = true;
|
||||
node.attribute(STR("attr5")) = true;
|
||||
xml_attribute() = true;
|
||||
|
||||
CHECK_NODE(node, "<node attr1=\"v1\" attr2=\"-2147483648\" attr3=\"2147483647\" attr4=\"0.5\" attr5=\"true\" />");
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483648\" attr3=\"2147483647\" attr4=\"0.5\" attr5=\"true\" />"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_set_value, "<node attr1='' attr2='' attr3='' attr4='' attr5=''/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.attribute("attr1").set_value("v1"));
|
||||
CHECK(!xml_attribute().set_value("v1"));
|
||||
CHECK(node.attribute(STR("attr1")).set_value(STR("v1")));
|
||||
CHECK(!xml_attribute().set_value(STR("v1")));
|
||||
|
||||
CHECK(node.attribute("attr2").set_value(-2147483647 - 1));
|
||||
CHECK(node.attribute(STR("attr2")).set_value(-2147483647 - 1));
|
||||
CHECK(!xml_attribute().set_value(-2147483647 - 1));
|
||||
|
||||
CHECK(node.attribute("attr3").set_value(2147483647u));
|
||||
CHECK(node.attribute(STR("attr3")).set_value(2147483647u));
|
||||
CHECK(!xml_attribute().set_value(2147483647));
|
||||
|
||||
CHECK(node.attribute("attr4").set_value(0.5));
|
||||
CHECK(node.attribute(STR("attr4")).set_value(0.5));
|
||||
CHECK(!xml_attribute().set_value(0.5));
|
||||
|
||||
CHECK(node.attribute("attr5").set_value(true));
|
||||
CHECK(node.attribute(STR("attr5")).set_value(true));
|
||||
CHECK(!xml_attribute().set_value(true));
|
||||
|
||||
CHECK_NODE(node, "<node attr1=\"v1\" attr2=\"-2147483648\" attr3=\"2147483647\" attr4=\"0.5\" attr5=\"true\" />");
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483648\" attr3=\"2147483647\" attr4=\"0.5\" attr5=\"true\" />"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_name, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child("node").set_name("n"));
|
||||
CHECK(!doc.child("node").first_child().set_name("n"));
|
||||
CHECK(!xml_node().set_name("n"));
|
||||
CHECK(doc.child(STR("node")).set_name(STR("n")));
|
||||
CHECK(!doc.child(STR("node")).first_child().set_name(STR("n")));
|
||||
CHECK(!xml_node().set_name(STR("n")));
|
||||
|
||||
CHECK_NODE(doc, "<n>text</n>");
|
||||
CHECK_NODE(doc, STR("<n>text</n>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child("node").first_child().set_value("no text"));
|
||||
CHECK(!doc.child("node").set_value("no text"));
|
||||
CHECK(!xml_node().set_value("no text"));
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text")));
|
||||
CHECK(!doc.child(STR("node")).set_value(STR("no text")));
|
||||
CHECK(!xml_node().set_value(STR("no text")));
|
||||
|
||||
CHECK_NODE(doc, "<node>no text</node>");
|
||||
CHECK_NODE(doc, STR("<node>no text</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_allocated, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text")));
|
||||
CHECK(!doc.child(STR("node")).set_value(STR("no text")));
|
||||
CHECK(!xml_node().set_value(STR("no text")));
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text at all")));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no text at all</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_attribute, "<node><child/></node>")
|
||||
{
|
||||
CHECK(xml_node().append_attribute("a") == xml_attribute());
|
||||
CHECK(doc.append_attribute("a") == xml_attribute());
|
||||
CHECK(xml_node().append_attribute(STR("a")) == xml_attribute());
|
||||
CHECK(doc.append_attribute(STR("a")) == xml_attribute());
|
||||
|
||||
xml_attribute a1 = doc.child("node").append_attribute("a1");
|
||||
xml_attribute a1 = doc.child(STR("node")).append_attribute(STR("a1"));
|
||||
CHECK(a1);
|
||||
a1 = "v1";
|
||||
a1 = STR("v1");
|
||||
|
||||
xml_attribute a2 = doc.child("node").append_attribute("a2");
|
||||
xml_attribute a2 = doc.child(STR("node")).append_attribute(STR("a2"));
|
||||
CHECK(a2 && a1 != a2);
|
||||
a2 = "v2";
|
||||
a2 = STR("v2");
|
||||
|
||||
xml_attribute a3 = doc.child("node").child("child").append_attribute("a3");
|
||||
xml_attribute a3 = doc.child(STR("node")).child(STR("child")).append_attribute(STR("a3"));
|
||||
CHECK(a3 && a1 != a3 && a2 != a3);
|
||||
a3 = "v3";
|
||||
a3 = STR("v3");
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a2=\"v2\"><child a3=\"v3\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a2=\"v2\"><child a3=\"v3\" /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_attribute_after, "<node a1='v1'><child a2='v2'/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_attribute_after("a", xml_attribute()) == xml_attribute());
|
||||
CHECK(xml_node().insert_attribute_after(STR("a"), xml_attribute()) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
xml_attribute a1 = node.attribute("a1");
|
||||
xml_attribute a2 = child.attribute("a2");
|
||||
xml_attribute a1 = node.attribute(STR("a1"));
|
||||
xml_attribute a2 = child.attribute(STR("a2"));
|
||||
|
||||
CHECK(node.insert_attribute_after("a", xml_attribute()) == xml_attribute());
|
||||
CHECK(node.insert_attribute_after("a", a2) == xml_attribute());
|
||||
CHECK(node.insert_attribute_after(STR("a"), xml_attribute()) == xml_attribute());
|
||||
CHECK(node.insert_attribute_after(STR("a"), a2) == xml_attribute());
|
||||
|
||||
xml_attribute a3 = node.insert_attribute_after("a3", a1);
|
||||
xml_attribute a3 = node.insert_attribute_after(STR("a3"), a1);
|
||||
CHECK(a3 && a3 != a2 && a3 != a1);
|
||||
a3 = "v3";
|
||||
a3 = STR("v3");
|
||||
|
||||
xml_attribute a4 = node.insert_attribute_after("a4", a1);
|
||||
xml_attribute a4 = node.insert_attribute_after(STR("a4"), a1);
|
||||
CHECK(a4 && a4 != a3 && a4 != a2 && a4 != a1);
|
||||
a4 = "v4";
|
||||
a4 = STR("v4");
|
||||
|
||||
xml_attribute a5 = node.insert_attribute_after("a5", a3);
|
||||
xml_attribute a5 = node.insert_attribute_after(STR("a5"), a3);
|
||||
CHECK(a5 && a5 != a4 && a5 != a3 && a5 != a2 && a5 != a1);
|
||||
a5 = "v5";
|
||||
a5 = STR("v5");
|
||||
|
||||
CHECK(child.insert_attribute_after("a", a4) == xml_attribute());
|
||||
CHECK(child.insert_attribute_after(STR("a"), a4) == xml_attribute());
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a4=\"v4\" a3=\"v3\" a5=\"v5\"><child a2=\"v2\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a4=\"v4\" a3=\"v3\" a5=\"v5\"><child a2=\"v2\" /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_attribute_before, "<node a1='v1'><child a2='v2'/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_attribute_before("a", xml_attribute()) == xml_attribute());
|
||||
CHECK(xml_node().insert_attribute_before(STR("a"), xml_attribute()) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
xml_attribute a1 = node.attribute("a1");
|
||||
xml_attribute a2 = child.attribute("a2");
|
||||
xml_attribute a1 = node.attribute(STR("a1"));
|
||||
xml_attribute a2 = child.attribute(STR("a2"));
|
||||
|
||||
CHECK(node.insert_attribute_before("a", xml_attribute()) == xml_attribute());
|
||||
CHECK(node.insert_attribute_before("a", a2) == xml_attribute());
|
||||
CHECK(node.insert_attribute_before(STR("a"), xml_attribute()) == xml_attribute());
|
||||
CHECK(node.insert_attribute_before(STR("a"), a2) == xml_attribute());
|
||||
|
||||
xml_attribute a3 = node.insert_attribute_before("a3", a1);
|
||||
xml_attribute a3 = node.insert_attribute_before(STR("a3"), a1);
|
||||
CHECK(a3 && a3 != a2 && a3 != a1);
|
||||
a3 = "v3";
|
||||
a3 = STR("v3");
|
||||
|
||||
xml_attribute a4 = node.insert_attribute_before("a4", a1);
|
||||
xml_attribute a4 = node.insert_attribute_before(STR("a4"), a1);
|
||||
CHECK(a4 && a4 != a3 && a4 != a2 && a4 != a1);
|
||||
a4 = "v4";
|
||||
a4 = STR("v4");
|
||||
|
||||
xml_attribute a5 = node.insert_attribute_before("a5", a3);
|
||||
xml_attribute a5 = node.insert_attribute_before(STR("a5"), a3);
|
||||
CHECK(a5 && a5 != a4 && a5 != a3 && a5 != a2 && a5 != a1);
|
||||
a5 = "v5";
|
||||
a5 = STR("v5");
|
||||
|
||||
CHECK(child.insert_attribute_before("a", a4) == xml_attribute());
|
||||
CHECK(child.insert_attribute_before(STR("a"), a4) == xml_attribute());
|
||||
|
||||
CHECK_NODE(doc, "<node a5=\"v5\" a3=\"v3\" a4=\"v4\" a1=\"v1\"><child a2=\"v2\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a5=\"v5\" a3=\"v3\" a4=\"v4\" a1=\"v1\"><child a2=\"v2\" /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_copy_attribute, "<node a1='v1'><child a2='v2'/><child/></node>")
|
||||
{
|
||||
CHECK(xml_node().append_copy(xml_attribute()) == xml_attribute());
|
||||
CHECK(xml_node().append_copy(doc.child("node").attribute("a1")) == xml_attribute());
|
||||
CHECK(doc.append_copy(doc.child("node").attribute("a1")) == xml_attribute());
|
||||
CHECK(xml_node().append_copy(doc.child(STR("node")).attribute(STR("a1"))) == xml_attribute());
|
||||
CHECK(doc.append_copy(doc.child(STR("node")).attribute(STR("a1"))) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
xml_attribute a1 = node.attribute("a1");
|
||||
xml_attribute a2 = child.attribute("a2");
|
||||
xml_attribute a1 = node.attribute(STR("a1"));
|
||||
xml_attribute a2 = child.attribute(STR("a2"));
|
||||
|
||||
xml_attribute a3 = node.append_copy(a1);
|
||||
CHECK(a3 && a3 != a2 && a3 != a1);
|
||||
|
@ -163,29 +175,29 @@ TEST_XML(dom_node_append_copy_attribute, "<node a1='v1'><child a2='v2'/><child/>
|
|||
xml_attribute a5 = node.last_child().append_copy(a1);
|
||||
CHECK(a5 && a5 != a4 && a5 != a3 && a5 != a2 && a5 != a1);
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a1=\"v1\" a2=\"v2\"><child a2=\"v2\" /><child a1=\"v1\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a1=\"v1\" a2=\"v2\"><child a2=\"v2\" /><child a1=\"v1\" /></node>"));
|
||||
|
||||
a3.set_name("a3");
|
||||
a3 = "v3";
|
||||
a3.set_name(STR("a3"));
|
||||
a3 = STR("v3");
|
||||
|
||||
a4.set_name("a4");
|
||||
a4 = "v4";
|
||||
a4.set_name(STR("a4"));
|
||||
a4 = STR("v4");
|
||||
|
||||
a5.set_name("a5");
|
||||
a5 = "v5";
|
||||
a5.set_name(STR("a5"));
|
||||
a5 = STR("v5");
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a3=\"v3\" a4=\"v4\"><child a2=\"v2\" /><child a5=\"v5\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a3=\"v3\" a4=\"v4\"><child a2=\"v2\" /><child a5=\"v5\" /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_copy_after_attribute, "<node a1='v1'><child a2='v2'/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_copy_after(xml_attribute(), xml_attribute()) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
xml_attribute a1 = node.attribute("a1");
|
||||
xml_attribute a2 = child.attribute("a2");
|
||||
xml_attribute a1 = node.attribute(STR("a1"));
|
||||
xml_attribute a2 = child.attribute(STR("a2"));
|
||||
|
||||
CHECK(node.insert_copy_after(a1, xml_attribute()) == xml_attribute());
|
||||
CHECK(node.insert_copy_after(xml_attribute(), a1) == xml_attribute());
|
||||
|
@ -202,29 +214,29 @@ TEST_XML(dom_node_insert_copy_after_attribute, "<node a1='v1'><child a2='v2'/></
|
|||
|
||||
CHECK(child.insert_copy_after(a4, a4) == xml_attribute());
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a2=\"v2\" a2=\"v2\" a1=\"v1\"><child a2=\"v2\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a2=\"v2\" a2=\"v2\" a1=\"v1\"><child a2=\"v2\" /></node>"));
|
||||
|
||||
a3.set_name("a3");
|
||||
a3 = "v3";
|
||||
a3.set_name(STR("a3"));
|
||||
a3 = STR("v3");
|
||||
|
||||
a4.set_name("a4");
|
||||
a4 = "v4";
|
||||
a4.set_name(STR("a4"));
|
||||
a4 = STR("v4");
|
||||
|
||||
a5.set_name("a5");
|
||||
a5 = "v5";
|
||||
a5.set_name(STR("a5"));
|
||||
a5 = STR("v5");
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a5=\"v5\" a4=\"v4\" a3=\"v3\"><child a2=\"v2\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a5=\"v5\" a4=\"v4\" a3=\"v3\"><child a2=\"v2\" /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_copy_before_attribute, "<node a1='v1'><child a2='v2'/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_copy_before(xml_attribute(), xml_attribute()) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
xml_attribute a1 = node.attribute("a1");
|
||||
xml_attribute a2 = child.attribute("a2");
|
||||
xml_attribute a1 = node.attribute(STR("a1"));
|
||||
xml_attribute a2 = child.attribute(STR("a2"));
|
||||
|
||||
CHECK(node.insert_copy_before(a1, xml_attribute()) == xml_attribute());
|
||||
CHECK(node.insert_copy_before(xml_attribute(), a1) == xml_attribute());
|
||||
|
@ -241,243 +253,254 @@ TEST_XML(dom_node_insert_copy_before_attribute, "<node a1='v1'><child a2='v2'/><
|
|||
|
||||
CHECK(child.insert_copy_before(a4, a4) == xml_attribute());
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a2=\"v2\" a2=\"v2\" a1=\"v1\"><child a2=\"v2\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a2=\"v2\" a2=\"v2\" a1=\"v1\"><child a2=\"v2\" /></node>"));
|
||||
|
||||
a3.set_name("a3");
|
||||
a3 = "v3";
|
||||
a3.set_name(STR("a3"));
|
||||
a3 = STR("v3");
|
||||
|
||||
a4.set_name("a4");
|
||||
a4 = "v4";
|
||||
a4.set_name(STR("a4"));
|
||||
a4 = STR("v4");
|
||||
|
||||
a5.set_name("a5");
|
||||
a5 = "v5";
|
||||
a5.set_name(STR("a5"));
|
||||
a5 = STR("v5");
|
||||
|
||||
CHECK_NODE(doc, "<node a3=\"v3\" a4=\"v4\" a5=\"v5\" a1=\"v1\"><child a2=\"v2\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a3=\"v3\" a4=\"v4\" a5=\"v5\" a1=\"v1\"><child a2=\"v2\" /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_attribute, "<node a1='v1' a2='v2' a3='v3'><child a4='v4'/></node>")
|
||||
{
|
||||
xml_node().remove_attribute("a");
|
||||
xml_node().remove_attribute(STR("a"));
|
||||
xml_node().remove_attribute(xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
node.remove_attribute("a");
|
||||
node.remove_attribute(STR("a"));
|
||||
node.remove_attribute(xml_attribute());
|
||||
node.remove_attribute(child.attribute("a4"));
|
||||
node.remove_attribute(child.attribute(STR("a4")));
|
||||
|
||||
CHECK_NODE(doc, "<node a1=\"v1\" a2=\"v2\" a3=\"v3\"><child a4=\"v4\" /></node>");
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a2=\"v2\" a3=\"v3\"><child a4=\"v4\" /></node>"));
|
||||
|
||||
node.remove_attribute("a1");
|
||||
node.remove_attribute(node.attribute("a3"));
|
||||
child.remove_attribute("a4");
|
||||
node.remove_attribute(STR("a1"));
|
||||
node.remove_attribute(node.attribute(STR("a3")));
|
||||
child.remove_attribute(STR("a4"));
|
||||
|
||||
CHECK_NODE(doc, "<node a2=\"v2\"><child /></node>");
|
||||
CHECK_NODE(doc, STR("<node a2=\"v2\"><child /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_child, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().append_child() == xml_node());
|
||||
CHECK(doc.child("node").first_child().append_child() == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().append_child() == xml_node());
|
||||
CHECK(doc.append_child(node_document) == xml_node());
|
||||
CHECK(doc.append_child(node_null) == xml_node());
|
||||
|
||||
xml_node n1 = doc.child("node").append_child();
|
||||
xml_node n1 = doc.child(STR("node")).append_child();
|
||||
CHECK(n1);
|
||||
CHECK(n1.set_name("n1"));
|
||||
CHECK(n1.set_name(STR("n1")));
|
||||
|
||||
xml_node n2 = doc.child("node").append_child();
|
||||
xml_node n2 = doc.child(STR("node")).append_child();
|
||||
CHECK(n2 && n1 != n2);
|
||||
CHECK(n2.set_name("n2"));
|
||||
CHECK(n2.set_name(STR("n2")));
|
||||
|
||||
xml_node n3 = doc.child("node").child("child").append_child(node_pcdata);
|
||||
xml_node n3 = doc.child(STR("node")).child(STR("child")).append_child(node_pcdata);
|
||||
CHECK(n3 && n1 != n3 && n2 != n3);
|
||||
CHECK(n3.set_value("n3"));
|
||||
CHECK(n3.set_value(STR("n3")));
|
||||
|
||||
xml_node n4 = doc.append_child(node_comment);
|
||||
CHECK(n4 && n1 != n4 && n2 != n4 && n3 != n4);
|
||||
CHECK(n4.set_value("n4"));
|
||||
CHECK(n4.set_value(STR("n4")));
|
||||
|
||||
CHECK_NODE(doc, "<node>foo<child>n3</child><n1 /><n2 /></node><!--n4-->");
|
||||
CHECK_NODE(doc, STR("<node>foo<child>n3</child><n1 /><n2 /></node><!--n4-->"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_child_after, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_child_after(node_element, xml_node()) == xml_node());
|
||||
CHECK(doc.child("node").first_child().insert_child_after(node_element, xml_node()) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().insert_child_after(node_element, xml_node()) == xml_node());
|
||||
CHECK(doc.insert_child_after(node_document, xml_node()) == xml_node());
|
||||
CHECK(doc.insert_child_after(node_null, xml_node()) == xml_node());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
CHECK(node.insert_child_after(node_element, node) == xml_node());
|
||||
CHECK(child.insert_child_after(node_element, node) == xml_node());
|
||||
|
||||
xml_node n1 = node.insert_child_after(node_element, child);
|
||||
CHECK(n1 && n1 != node && n1 != child);
|
||||
CHECK(n1.set_name("n1"));
|
||||
CHECK(n1.set_name(STR("n1")));
|
||||
|
||||
xml_node n2 = node.insert_child_after(node_element, child);
|
||||
CHECK(n2 && n2 != node && n2 != child && n2 != n1);
|
||||
CHECK(n2.set_name("n2"));
|
||||
CHECK(n2.set_name(STR("n2")));
|
||||
|
||||
xml_node n3 = node.insert_child_after(node_pcdata, n2);
|
||||
CHECK(n3 && n3 != node && n3 != child && n3 != n1 && n3 != n2);
|
||||
CHECK(n3.set_value("n3"));
|
||||
CHECK(n3.set_value(STR("n3")));
|
||||
|
||||
xml_node n4 = node.insert_child_after(node_pi, node.first_child());
|
||||
CHECK(n4 && n4 != node && n4 != child && n4 != n1 && n4 != n2 && n4 != n3);
|
||||
CHECK(n4.set_name("n4"));
|
||||
CHECK(n4.set_name(STR("n4")));
|
||||
|
||||
CHECK(child.insert_child_after(node_element, n3) == xml_node());
|
||||
|
||||
CHECK_NODE(doc, "<node>foo<?n4?><child /><n2 />n3<n1 /></node>");
|
||||
CHECK_NODE(doc, STR("<node>foo<?n4?><child /><n2 />n3<n1 /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_child_before, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_child_before(node_element, xml_node()) == xml_node());
|
||||
CHECK(doc.child("node").first_child().insert_child_before(node_element, xml_node()) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().insert_child_before(node_element, xml_node()) == xml_node());
|
||||
CHECK(doc.insert_child_before(node_document, xml_node()) == xml_node());
|
||||
CHECK(doc.insert_child_before(node_null, xml_node()) == xml_node());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
CHECK(node.insert_child_before(node_element, node) == xml_node());
|
||||
CHECK(child.insert_child_before(node_element, node) == xml_node());
|
||||
|
||||
xml_node n1 = node.insert_child_before(node_element, child);
|
||||
CHECK(n1 && n1 != node && n1 != child);
|
||||
CHECK(n1.set_name("n1"));
|
||||
CHECK(n1.set_name(STR("n1")));
|
||||
|
||||
xml_node n2 = node.insert_child_before(node_element, child);
|
||||
CHECK(n2 && n2 != node && n2 != child && n2 != n1);
|
||||
CHECK(n2.set_name("n2"));
|
||||
CHECK(n2.set_name(STR("n2")));
|
||||
|
||||
xml_node n3 = node.insert_child_before(node_pcdata, n2);
|
||||
CHECK(n3 && n3 != node && n3 != child && n3 != n1 && n3 != n2);
|
||||
CHECK(n3.set_value("n3"));
|
||||
CHECK(n3.set_value(STR("n3")));
|
||||
|
||||
xml_node n4 = node.insert_child_before(node_pi, node.first_child());
|
||||
CHECK(n4 && n4 != node && n4 != child && n4 != n1 && n4 != n2 && n4 != n3);
|
||||
CHECK(n4.set_name("n4"));
|
||||
CHECK(n4.set_name(STR("n4")));
|
||||
|
||||
CHECK(child.insert_child_before(node_element, n3) == xml_node());
|
||||
|
||||
CHECK_NODE(doc, "<node><?n4?>foo<n1 />n3<n2 /><child /></node>");
|
||||
CHECK_NODE(doc, STR("<node><?n4?>foo<n1 />n3<n2 /><child /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_child, "<node><n1/><n2/><n3/><child><n4/></child></node>")
|
||||
{
|
||||
xml_node().remove_child("a");
|
||||
xml_node().remove_child(STR("a"));
|
||||
xml_node().remove_child(xml_node());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node child = node.child("child");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
node.remove_child("a");
|
||||
node.remove_child(STR("a"));
|
||||
node.remove_child(xml_node());
|
||||
node.remove_child(child.child("n4"));
|
||||
node.remove_child(child.child(STR("n4")));
|
||||
|
||||
CHECK_NODE(doc, "<node><n1 /><n2 /><n3 /><child><n4 /></child></node>");
|
||||
CHECK_NODE(doc, STR("<node><n1 /><n2 /><n3 /><child><n4 /></child></node>"));
|
||||
|
||||
node.remove_child("n1");
|
||||
node.remove_child(node.child("n3"));
|
||||
child.remove_child("n4");
|
||||
node.remove_child(STR("n1"));
|
||||
node.remove_child(node.child(STR("n3")));
|
||||
child.remove_child(STR("n4"));
|
||||
|
||||
CHECK_NODE(doc, "<node><n2 /><child /></node>");
|
||||
CHECK_NODE(doc, STR("<node><n2 /><child /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_copy, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().append_copy(xml_node()) == xml_node());
|
||||
CHECK(doc.child("node").first_child().append_copy(doc.child("node")) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().append_copy(doc.child(STR("node"))) == xml_node());
|
||||
CHECK(doc.append_copy(doc) == xml_node());
|
||||
CHECK(doc.append_copy(xml_node()) == xml_node());
|
||||
|
||||
xml_node n1 = doc.child("node").append_copy(doc.child("node").first_child());
|
||||
xml_node n1 = doc.child(STR("node")).append_copy(doc.child(STR("node")).first_child());
|
||||
CHECK(n1);
|
||||
CHECK_STRING(n1.value(), "foo");
|
||||
CHECK_NODE(doc, "<node>foo<child />foo</node>");
|
||||
CHECK_STRING(n1.value(), STR("foo"));
|
||||
CHECK_NODE(doc, STR("<node>foo<child />foo</node>"));
|
||||
|
||||
xml_node n2 = doc.child("node").append_copy(doc.child("node").child("child"));
|
||||
xml_node n2 = doc.child(STR("node")).append_copy(doc.child(STR("node")).child(STR("child")));
|
||||
CHECK(n2 && n2 != n1);
|
||||
CHECK_STRING(n2.name(), "child");
|
||||
CHECK_NODE(doc, "<node>foo<child />foo<child /></node>");
|
||||
CHECK_STRING(n2.name(), STR("child"));
|
||||
CHECK_NODE(doc, STR("<node>foo<child />foo<child /></node>"));
|
||||
|
||||
xml_node n3 = doc.child("node").child("child").append_copy(doc.child("node").first_child());
|
||||
xml_node n3 = doc.child(STR("node")).child(STR("child")).append_copy(doc.child(STR("node")).first_child());
|
||||
CHECK(n3 && n3 != n1 && n3 != n2);
|
||||
CHECK_STRING(n3.value(), "foo");
|
||||
CHECK_NODE(doc, "<node>foo<child>foo</child>foo<child /></node>");
|
||||
CHECK_STRING(n3.value(), STR("foo"));
|
||||
CHECK_NODE(doc, STR("<node>foo<child>foo</child>foo<child /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_copy_after, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_copy_after(xml_node(), xml_node()) == xml_node());
|
||||
CHECK(doc.child("node").first_child().insert_copy_after(doc.child("node"), doc.child("node")) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().insert_copy_after(doc.child(STR("node")), doc.child(STR("node"))) == xml_node());
|
||||
CHECK(doc.insert_copy_after(doc, doc) == xml_node());
|
||||
CHECK(doc.insert_copy_after(xml_node(), doc.child("node")) == xml_node());
|
||||
CHECK(doc.insert_copy_after(doc.child("node"), xml_node()) == xml_node());
|
||||
CHECK(doc.insert_copy_after(xml_node(), doc.child(STR("node"))) == xml_node());
|
||||
CHECK(doc.insert_copy_after(doc.child(STR("node")), xml_node()) == xml_node());
|
||||
|
||||
xml_node n1 = doc.child("node").insert_copy_after(doc.child("node").child("child"), doc.child("node").first_child());
|
||||
xml_node n1 = doc.child(STR("node")).insert_copy_after(doc.child(STR("node")).child(STR("child")), doc.child(STR("node")).first_child());
|
||||
CHECK(n1);
|
||||
CHECK_STRING(n1.name(), "child");
|
||||
CHECK_NODE(doc, "<node>foo<child /><child /></node>");
|
||||
CHECK_STRING(n1.name(), STR("child"));
|
||||
CHECK_NODE(doc, STR("<node>foo<child /><child /></node>"));
|
||||
|
||||
xml_node n2 = doc.child("node").insert_copy_after(doc.child("node").first_child(), doc.child("node").last_child());
|
||||
xml_node n2 = doc.child(STR("node")).insert_copy_after(doc.child(STR("node")).first_child(), doc.child(STR("node")).last_child());
|
||||
CHECK(n2 && n2 != n1);
|
||||
CHECK_STRING(n2.value(), "foo");
|
||||
CHECK_NODE(doc, "<node>foo<child /><child />foo</node>");
|
||||
CHECK_STRING(n2.value(), STR("foo"));
|
||||
CHECK_NODE(doc, STR("<node>foo<child /><child />foo</node>"));
|
||||
|
||||
xml_node n3 = doc.child("node").insert_copy_after(doc.child("node").first_child(), doc.child("node").first_child());
|
||||
xml_node n3 = doc.child(STR("node")).insert_copy_after(doc.child(STR("node")).first_child(), doc.child(STR("node")).first_child());
|
||||
CHECK(n3 && n3 != n1 && n3 != n2);
|
||||
CHECK_STRING(n3.value(), "foo");
|
||||
CHECK_NODE(doc, "<node>foofoo<child /><child />foo</node>");
|
||||
CHECK_STRING(n3.value(), STR("foo"));
|
||||
CHECK_NODE(doc, STR("<node>foofoo<child /><child />foo</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_copy_before, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_copy_before(xml_node(), xml_node()) == xml_node());
|
||||
CHECK(doc.child("node").first_child().insert_copy_before(doc.child("node"), doc.child("node")) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().insert_copy_before(doc.child(STR("node")), doc.child(STR("node"))) == xml_node());
|
||||
CHECK(doc.insert_copy_before(doc, doc) == xml_node());
|
||||
CHECK(doc.insert_copy_before(xml_node(), doc.child("node")) == xml_node());
|
||||
CHECK(doc.insert_copy_before(doc.child("node"), xml_node()) == xml_node());
|
||||
CHECK(doc.insert_copy_before(xml_node(), doc.child(STR("node"))) == xml_node());
|
||||
CHECK(doc.insert_copy_before(doc.child(STR("node")), xml_node()) == xml_node());
|
||||
|
||||
xml_node n1 = doc.child("node").insert_copy_before(doc.child("node").child("child"), doc.child("node").first_child());
|
||||
xml_node n1 = doc.child(STR("node")).insert_copy_before(doc.child(STR("node")).child(STR("child")), doc.child(STR("node")).first_child());
|
||||
CHECK(n1);
|
||||
CHECK_STRING(n1.name(), "child");
|
||||
CHECK_NODE(doc, "<node><child />foo<child /></node>");
|
||||
CHECK_STRING(n1.name(), STR("child"));
|
||||
CHECK_NODE(doc, STR("<node><child />foo<child /></node>"));
|
||||
|
||||
xml_node n2 = doc.child("node").insert_copy_before(doc.child("node").first_child(), doc.child("node").last_child());
|
||||
xml_node n2 = doc.child(STR("node")).insert_copy_before(doc.child(STR("node")).first_child(), doc.child(STR("node")).last_child());
|
||||
CHECK(n2 && n2 != n1);
|
||||
CHECK_STRING(n2.name(), "child");
|
||||
CHECK_NODE(doc, "<node><child />foo<child /><child /></node>");
|
||||
CHECK_STRING(n2.name(), STR("child"));
|
||||
CHECK_NODE(doc, STR("<node><child />foo<child /><child /></node>"));
|
||||
|
||||
xml_node n3 = doc.child("node").insert_copy_before(doc.child("node").first_child().next_sibling(), doc.child("node").first_child());
|
||||
xml_node n3 = doc.child(STR("node")).insert_copy_before(doc.child(STR("node")).first_child().next_sibling(), doc.child(STR("node")).first_child());
|
||||
CHECK(n3 && n3 != n1 && n3 != n2);
|
||||
CHECK_STRING(n3.value(), "foo");
|
||||
CHECK_NODE(doc, "<node>foo<child />foo<child /><child /></node>");
|
||||
CHECK_STRING(n3.value(), STR("foo"));
|
||||
CHECK_NODE(doc, STR("<node>foo<child />foo<child /><child /></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_copy_recursive, "<node>foo<child/></node>")
|
||||
{
|
||||
doc.child("node").append_copy(doc.child("node"));
|
||||
CHECK_NODE(doc, "<node>foo<child /><node>foo<child /></node></node>");
|
||||
doc.child(STR("node")).append_copy(doc.child(STR("node")));
|
||||
CHECK_NODE(doc, STR("<node>foo<child /><node>foo<child /></node></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_copy_crossdoc, "<node/>")
|
||||
{
|
||||
xml_document newdoc;
|
||||
newdoc.append_copy(doc.child("node"));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK_NODE(newdoc, "<node />");
|
||||
newdoc.append_copy(doc.child(STR("node")));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
CHECK_NODE(newdoc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(dom_node_copy_types, "<root><?xml version='1.0'?><?pi value?><!--comment--><node id='1'>pcdata<![CDATA[cdata]]></node></root>", parse_default | parse_pi | parse_comments | parse_declaration)
|
||||
{
|
||||
doc.append_copy(doc.child("root"));
|
||||
CHECK_NODE(doc, "<root><?xml version=\"1.0\"?><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root><root><?xml version=\"1.0\"?><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root>");
|
||||
doc.append_copy(doc.child(STR("root")));
|
||||
CHECK_NODE(doc, STR("<root><?xml version=\"1.0\"?><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root><root><?xml version=\"1.0\"?><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_assign_large, "<node attr1='' attr2='' />")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
node.attribute(STR("attr1")) = FLT_MAX;
|
||||
node.attribute(STR("attr2")) = DBL_MAX;
|
||||
|
||||
CHECK(test_node(node, STR("<node attr1=\"3.40282e+038\" attr2=\"1.79769e+308\" />"), STR(""), pugi::format_raw) ||
|
||||
test_node(node, STR("<node attr1=\"3.40282e+38\" attr2=\"1.79769e+308\" />"), STR(""), pugi::format_raw));
|
||||
}
|
||||
|
|
|
@ -2,9 +2,13 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
|
@ -37,28 +41,28 @@ template <typename T> static void generic_empty_test(const T& obj)
|
|||
|
||||
TEST_XML(dom_attr_bool_ops, "<node attr='1'/>")
|
||||
{
|
||||
generic_bool_ops_test(doc.child("node").attribute("attr"));
|
||||
generic_bool_ops_test(doc.child(STR("node")).attribute(STR("attr")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_eq_ops, "<node attr1='1' attr2='2'/>")
|
||||
{
|
||||
generic_eq_ops_test(doc.child("node").attribute("attr1"), doc.child("node").attribute("attr2"));
|
||||
generic_eq_ops_test(doc.child(STR("node")).attribute(STR("attr1")), doc.child(STR("node")).attribute(STR("attr2")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_rel_ops, "<node attr1='1' attr2='2'/>")
|
||||
{
|
||||
generic_rel_ops_test(doc.child("node").attribute("attr1"), doc.child("node").attribute("attr2"));
|
||||
generic_rel_ops_test(doc.child(STR("node")).attribute(STR("attr1")), doc.child(STR("node")).attribute(STR("attr2")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_empty, "<node attr='1'/>")
|
||||
{
|
||||
generic_empty_test(doc.child("node").attribute("attr"));
|
||||
generic_empty_test(doc.child(STR("node")).attribute(STR("attr")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_next_previous_attribute, "<node attr1='1' attr2='2' />")
|
||||
{
|
||||
xml_attribute attr1 = doc.child("node").attribute("attr1");
|
||||
xml_attribute attr2 = doc.child("node").attribute("attr2");
|
||||
xml_attribute attr1 = doc.child(STR("node")).attribute(STR("attr1"));
|
||||
xml_attribute attr2 = doc.child(STR("node")).attribute(STR("attr2"));
|
||||
|
||||
CHECK(attr1.next_attribute() == attr2);
|
||||
CHECK(attr2.next_attribute() == xml_attribute());
|
||||
|
@ -72,87 +76,87 @@ TEST_XML(dom_attr_next_previous_attribute, "<node attr1='1' attr2='2' />")
|
|||
|
||||
TEST_XML(dom_attr_name_value, "<node attr='1'/>")
|
||||
{
|
||||
xml_attribute attr = doc.child("node").attribute("attr");
|
||||
xml_attribute attr = doc.child(STR("node")).attribute(STR("attr"));
|
||||
|
||||
CHECK_NAME_VALUE(attr, "attr", "1");
|
||||
CHECK_NAME_VALUE(xml_attribute(), "", "");
|
||||
CHECK_NAME_VALUE(attr, STR("attr"), STR("1"));
|
||||
CHECK_NAME_VALUE(xml_attribute(), STR(""), STR(""));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_as_int, "<node attr1='1' attr2='-1' attr3='-2147483648' attr4='2147483647'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(xml_attribute().as_int() == 0);
|
||||
CHECK(node.attribute("attr1").as_int() == 1);
|
||||
CHECK(node.attribute("attr2").as_int() == -1);
|
||||
CHECK(node.attribute("attr3").as_int() == -2147483647 - 1);
|
||||
CHECK(node.attribute("attr4").as_int() == 2147483647);
|
||||
CHECK(node.attribute(STR("attr1")).as_int() == 1);
|
||||
CHECK(node.attribute(STR("attr2")).as_int() == -1);
|
||||
CHECK(node.attribute(STR("attr3")).as_int() == -2147483647 - 1);
|
||||
CHECK(node.attribute(STR("attr4")).as_int() == 2147483647);
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_as_uint, "<node attr1='0' attr2='1' attr3='2147483647'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(xml_attribute().as_uint() == 0);
|
||||
CHECK(node.attribute("attr1").as_uint() == 0);
|
||||
CHECK(node.attribute("attr2").as_uint() == 1);
|
||||
CHECK(node.attribute("attr3").as_uint() == 2147483647);
|
||||
CHECK(node.attribute(STR("attr1")).as_uint() == 0);
|
||||
CHECK(node.attribute(STR("attr2")).as_uint() == 1);
|
||||
CHECK(node.attribute(STR("attr3")).as_uint() == 2147483647);
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_as_float, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(xml_attribute().as_float() == 0);
|
||||
CHECK_DOUBLE(node.attribute("attr1").as_float(), 0);
|
||||
CHECK_DOUBLE(node.attribute("attr2").as_float(), 1);
|
||||
CHECK_DOUBLE(node.attribute("attr3").as_float(), 0.12);
|
||||
CHECK_DOUBLE(node.attribute("attr4").as_float(), -5.1);
|
||||
CHECK_DOUBLE(node.attribute("attr5").as_float(), 3e-4);
|
||||
CHECK_DOUBLE(node.attribute("attr6").as_float(), 3.14159265358979323846);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr1")).as_float(), 0);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr2")).as_float(), 1);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr3")).as_float(), 0.12);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr4")).as_float(), -5.1);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr5")).as_float(), 3e-4);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr6")).as_float(), 3.14159265358979323846);
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_as_double, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(xml_attribute().as_double() == 0);
|
||||
CHECK_DOUBLE(node.attribute("attr1").as_double(), 0);
|
||||
CHECK_DOUBLE(node.attribute("attr2").as_double(), 1);
|
||||
CHECK_DOUBLE(node.attribute("attr3").as_double(), 0.12);
|
||||
CHECK_DOUBLE(node.attribute("attr4").as_double(), -5.1);
|
||||
CHECK_DOUBLE(node.attribute("attr5").as_double(), 3e-4);
|
||||
CHECK_DOUBLE(node.attribute("attr6").as_double(), 3.14159265358979323846);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr1")).as_double(), 0);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr2")).as_double(), 1);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr3")).as_double(), 0.12);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr4")).as_double(), -5.1);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr5")).as_double(), 3e-4);
|
||||
CHECK_DOUBLE(node.attribute(STR("attr6")).as_double(), 3.14159265358979323846);
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_as_bool, "<node attr1='0' attr2='1' attr3='true' attr4='True' attr5='Yes' attr6='yes' attr7='false'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(!xml_attribute().as_bool());
|
||||
CHECK(!node.attribute("attr1").as_bool());
|
||||
CHECK(node.attribute("attr2").as_bool());
|
||||
CHECK(node.attribute("attr3").as_bool());
|
||||
CHECK(node.attribute("attr4").as_bool());
|
||||
CHECK(node.attribute("attr5").as_bool());
|
||||
CHECK(node.attribute("attr6").as_bool());
|
||||
CHECK(!node.attribute("attr7").as_bool());
|
||||
CHECK(!node.attribute(STR("attr1")).as_bool());
|
||||
CHECK(node.attribute(STR("attr2")).as_bool());
|
||||
CHECK(node.attribute(STR("attr3")).as_bool());
|
||||
CHECK(node.attribute(STR("attr4")).as_bool());
|
||||
CHECK(node.attribute(STR("attr5")).as_bool());
|
||||
CHECK(node.attribute(STR("attr6")).as_bool());
|
||||
CHECK(!node.attribute(STR("attr7")).as_bool());
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_iterator, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>")
|
||||
{
|
||||
xml_node node1 = doc.child("node").child("node1");
|
||||
xml_node node2 = doc.child("node").child("node2");
|
||||
xml_node node3 = doc.child("node").child("node3");
|
||||
xml_node node1 = doc.child(STR("node")).child(STR("node1"));
|
||||
xml_node node2 = doc.child(STR("node")).child(STR("node2"));
|
||||
xml_node node3 = doc.child(STR("node")).child(STR("node3"));
|
||||
|
||||
CHECK(xml_node().attributes_begin() == xml_attribute_iterator());
|
||||
CHECK(xml_node().attributes_end() == xml_attribute_iterator());
|
||||
|
||||
CHECK(node1.attributes_begin() == xml_attribute_iterator(node1.attribute("attr1")));
|
||||
CHECK(node1.attributes_begin() == xml_attribute_iterator(node1.attribute(STR("attr1"))));
|
||||
CHECK(move_iter(node1.attributes_begin(), 1) == node1.attributes_end());
|
||||
CHECK(move_iter(node1.attributes_end(), -1) == node1.attributes_begin());
|
||||
CHECK(*node1.attributes_begin() == node1.attribute("attr1"));
|
||||
CHECK_STRING(node1.attributes_begin()->name(), "attr1");
|
||||
CHECK(*node1.attributes_begin() == node1.attribute(STR("attr1")));
|
||||
CHECK_STRING(node1.attributes_begin()->name(), STR("attr1"));
|
||||
|
||||
CHECK(move_iter(node2.attributes_begin(), 2) == node2.attributes_end());
|
||||
CHECK(move_iter(node2.attributes_end(), -2) == node2.attributes_begin());
|
||||
|
@ -160,7 +164,7 @@ TEST_XML(dom_attr_iterator, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/
|
|||
CHECK(node3.attributes_begin() == xml_attribute_iterator());
|
||||
CHECK(node3.attributes_begin() == node3.attributes_end());
|
||||
|
||||
xml_attribute_iterator it = node2.attribute("attr2");
|
||||
xml_attribute_iterator it = node2.attribute(STR("attr2"));
|
||||
xml_attribute_iterator itt = it;
|
||||
|
||||
CHECK(itt++ == it);
|
||||
|
@ -180,38 +184,38 @@ TEST_XML(dom_attr_iterator, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/
|
|||
|
||||
TEST_XML(dom_node_bool_ops, "<node/>")
|
||||
{
|
||||
generic_bool_ops_test(doc.child("node"));
|
||||
generic_bool_ops_test(doc.child(STR("node")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_eq_ops, "<node><node1/><node2/></node>")
|
||||
{
|
||||
generic_eq_ops_test(doc.child("node").child("node1"), doc.child("node").child("node2"));
|
||||
generic_eq_ops_test(doc.child(STR("node")).child(STR("node1")), doc.child(STR("node")).child(STR("node2")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_rel_ops, "<node><node1/><node2/></node>")
|
||||
{
|
||||
generic_rel_ops_test(doc.child("node").child("node1"), doc.child("node").child("node2"));
|
||||
generic_rel_ops_test(doc.child(STR("node")).child(STR("node1")), doc.child(STR("node")).child(STR("node2")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_empty, "<node/>")
|
||||
{
|
||||
generic_empty_test(doc.child("node"));
|
||||
generic_empty_test(doc.child(STR("node")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_iterator, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>")
|
||||
{
|
||||
xml_node node1 = doc.child("node").child("node1");
|
||||
xml_node node2 = doc.child("node").child("node2");
|
||||
xml_node node3 = doc.child("node").child("node3");
|
||||
xml_node node1 = doc.child(STR("node")).child(STR("node1"));
|
||||
xml_node node2 = doc.child(STR("node")).child(STR("node2"));
|
||||
xml_node node3 = doc.child(STR("node")).child(STR("node3"));
|
||||
|
||||
CHECK(xml_node().begin() == xml_node_iterator());
|
||||
CHECK(xml_node().end() == xml_node_iterator());
|
||||
|
||||
CHECK(node1.begin() == xml_node_iterator(node1.child("child1")));
|
||||
CHECK(node1.begin() == xml_node_iterator(node1.child(STR("child1"))));
|
||||
CHECK(move_iter(node1.begin(), 1) == node1.end());
|
||||
CHECK(move_iter(node1.end(), -1) == node1.begin());
|
||||
CHECK(*node1.begin() == node1.child("child1"));
|
||||
CHECK_STRING(node1.begin()->name(), "child1");
|
||||
CHECK(*node1.begin() == node1.child(STR("child1")));
|
||||
CHECK_STRING(node1.begin()->name(), STR("child1"));
|
||||
|
||||
CHECK(move_iter(node2.begin(), 2) == node2.end());
|
||||
CHECK(move_iter(node2.end(), -2) == node2.begin());
|
||||
|
@ -219,7 +223,7 @@ TEST_XML(dom_node_iterator, "<node><node1><child1/></node1><node2><child1/><chil
|
|||
CHECK(node3.begin() == xml_node_iterator());
|
||||
CHECK(node3.begin() == node3.end());
|
||||
|
||||
xml_node_iterator it = node2.child("child2");
|
||||
xml_node_iterator it = node2.child(STR("child2"));
|
||||
xml_node_iterator itt = it;
|
||||
|
||||
CHECK(itt++ == it);
|
||||
|
@ -240,15 +244,15 @@ TEST_XML(dom_node_iterator, "<node><node1><child1/></node1><node2><child1/><chil
|
|||
TEST_XML(dom_node_parent, "<node><child/></node>")
|
||||
{
|
||||
CHECK(xml_node().parent() == xml_node());
|
||||
CHECK(doc.child("node").child("child").parent() == doc.child("node"));
|
||||
CHECK(doc.child("node").parent() == doc);
|
||||
CHECK(doc.child(STR("node")).child(STR("child")).parent() == doc.child(STR("node")));
|
||||
CHECK(doc.child(STR("node")).parent() == doc);
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_root, "<node><child/></node>")
|
||||
{
|
||||
CHECK(xml_node().root() == xml_node());
|
||||
CHECK(doc.child("node").child("child").root() == doc);
|
||||
CHECK(doc.child("node").root() == doc);
|
||||
CHECK(doc.child(STR("node")).child(STR("child")).root() == doc);
|
||||
CHECK(doc.child(STR("node")).root() == doc);
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(dom_node_type, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration)
|
||||
|
@ -263,7 +267,7 @@ TEST_XML_FLAGS(dom_node_type, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[c
|
|||
CHECK((it++)->type() == node_comment);
|
||||
CHECK((it++)->type() == node_element);
|
||||
|
||||
xml_node_iterator cit = doc.child("node").begin();
|
||||
xml_node_iterator cit = doc.child(STR("node")).begin();
|
||||
|
||||
CHECK((cit++)->type() == node_pcdata);
|
||||
CHECK((cit++)->type() == node_cdata);
|
||||
|
@ -271,64 +275,64 @@ TEST_XML_FLAGS(dom_node_type, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[c
|
|||
|
||||
TEST_XML_FLAGS(dom_node_name_value, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration)
|
||||
{
|
||||
CHECK_NAME_VALUE(xml_node(), "", "");
|
||||
CHECK_NAME_VALUE(doc, "", "");
|
||||
CHECK_NAME_VALUE(xml_node(), STR(""), STR(""));
|
||||
CHECK_NAME_VALUE(doc, STR(""), STR(""));
|
||||
|
||||
xml_node_iterator it = doc.begin();
|
||||
|
||||
CHECK_NAME_VALUE(*it++, "xml", "");
|
||||
CHECK_NAME_VALUE(*it++, "pi", "");
|
||||
CHECK_NAME_VALUE(*it++, "", "comment");
|
||||
CHECK_NAME_VALUE(*it++, "node", "");
|
||||
CHECK_NAME_VALUE(*it++, STR("xml"), STR(""));
|
||||
CHECK_NAME_VALUE(*it++, STR("pi"), STR(""));
|
||||
CHECK_NAME_VALUE(*it++, STR(""), STR("comment"));
|
||||
CHECK_NAME_VALUE(*it++, STR("node"), STR(""));
|
||||
|
||||
xml_node_iterator cit = doc.child("node").begin();
|
||||
xml_node_iterator cit = doc.child(STR("node")).begin();
|
||||
|
||||
CHECK_NAME_VALUE(*cit++, "", "pcdata");
|
||||
CHECK_NAME_VALUE(*cit++, "", "cdata");
|
||||
CHECK_NAME_VALUE(*cit++, STR(""), STR("pcdata"));
|
||||
CHECK_NAME_VALUE(*cit++, STR(""), STR("cdata"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_child, "<node><child1/><child2/></node>")
|
||||
{
|
||||
CHECK(xml_node().child("n") == xml_node());
|
||||
CHECK(xml_node().child(STR("n")) == xml_node());
|
||||
|
||||
CHECK(doc.child("n") == xml_node());
|
||||
CHECK_NAME_VALUE(doc.child("node"), "node", "");
|
||||
CHECK(doc.child("node").child("child2") == doc.child("node").last_child());
|
||||
CHECK(doc.child(STR("n")) == xml_node());
|
||||
CHECK_NAME_VALUE(doc.child(STR("node")), STR("node"), STR(""));
|
||||
CHECK(doc.child(STR("node")).child(STR("child2")) == doc.child(STR("node")).last_child());
|
||||
|
||||
CHECK(doc.child_w("n?de") == doc.child("node"));
|
||||
CHECK(doc.child_w("n[az]de") == xml_node());
|
||||
CHECK(doc.child_w("n[aoz]de") == doc.child("node"));
|
||||
CHECK(doc.child_w("*e") == doc.child("node"));
|
||||
CHECK(doc.child("node").child_w("*l?[23456789]*") == doc.child("node").child("child2"));
|
||||
CHECK(doc.child_w(STR("n?de")) == doc.child(STR("node")));
|
||||
CHECK(doc.child_w(STR("n[az]de")) == xml_node());
|
||||
CHECK(doc.child_w(STR("n[aoz]de")) == doc.child(STR("node")));
|
||||
CHECK(doc.child_w(STR("*e")) == doc.child(STR("node")));
|
||||
CHECK(doc.child(STR("node")).child_w(STR("*l?[23456789]*")) == doc.child(STR("node")).child(STR("child2")));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_attribute, "<node attr1='0' attr2='1'/>")
|
||||
{
|
||||
CHECK(xml_node().attribute("a") == xml_attribute());
|
||||
CHECK(xml_node().attribute(STR("a")) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.attribute("n") == xml_attribute());
|
||||
CHECK_NAME_VALUE(node.attribute("attr1"), "attr1", "0");
|
||||
CHECK(node.attribute("attr2") == node.last_attribute());
|
||||
CHECK(node.attribute(STR("n")) == xml_attribute());
|
||||
CHECK_NAME_VALUE(node.attribute(STR("attr1")), STR("attr1"), STR("0"));
|
||||
CHECK(node.attribute(STR("attr2")) == node.last_attribute());
|
||||
|
||||
CHECK(node.attribute_w("*tt?[23456789]*") == node.attribute("attr2"));
|
||||
CHECK(node.attribute_w("?") == xml_attribute());
|
||||
CHECK(node.attribute_w(STR("*tt?[23456789]*")) == node.attribute(STR("attr2")));
|
||||
CHECK(node.attribute_w(STR("?")) == xml_attribute());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></node>")
|
||||
{
|
||||
CHECK(xml_node().next_sibling() == xml_node());
|
||||
CHECK(xml_node().next_sibling("n") == xml_node());
|
||||
CHECK(xml_node().next_sibling_w("n") == xml_node());
|
||||
CHECK(xml_node().next_sibling(STR("n")) == xml_node());
|
||||
CHECK(xml_node().next_sibling_w(STR("n")) == xml_node());
|
||||
|
||||
CHECK(xml_node().previous_sibling() == xml_node());
|
||||
CHECK(xml_node().previous_sibling("n") == xml_node());
|
||||
CHECK(xml_node().previous_sibling_w("n") == xml_node());
|
||||
CHECK(xml_node().previous_sibling(STR("n")) == xml_node());
|
||||
CHECK(xml_node().previous_sibling_w(STR("n")) == xml_node());
|
||||
|
||||
xml_node child1 = doc.child("node").child("child1");
|
||||
xml_node child2 = doc.child("node").child("child2");
|
||||
xml_node child3 = doc.child("node").child("child3");
|
||||
xml_node child1 = doc.child(STR("node")).child(STR("child1"));
|
||||
xml_node child2 = doc.child(STR("node")).child(STR("child2"));
|
||||
xml_node child3 = doc.child(STR("node")).child(STR("child3"));
|
||||
|
||||
CHECK(child1.next_sibling() == child2);
|
||||
CHECK(child3.next_sibling() == xml_node());
|
||||
|
@ -336,41 +340,42 @@ TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></nod
|
|||
CHECK(child1.previous_sibling() == xml_node());
|
||||
CHECK(child3.previous_sibling() == child2);
|
||||
|
||||
CHECK(child1.next_sibling("child3") == child3);
|
||||
CHECK(child1.next_sibling("child") == xml_node());
|
||||
CHECK(child1.next_sibling(STR("child3")) == child3);
|
||||
CHECK(child1.next_sibling(STR("child")) == xml_node());
|
||||
|
||||
CHECK(child3.previous_sibling("child1") == child1);
|
||||
CHECK(child3.previous_sibling("child") == xml_node());
|
||||
CHECK(child3.previous_sibling(STR("child1")) == child1);
|
||||
CHECK(child3.previous_sibling(STR("child")) == xml_node());
|
||||
|
||||
CHECK(child1.next_sibling_w("*[3456789]") == child3);
|
||||
CHECK(child1.next_sibling_w("?") == xml_node());
|
||||
CHECK(child3.previous_sibling_w("*[3456789]") == xml_node());
|
||||
CHECK(child3.previous_sibling_w("?") == xml_node());
|
||||
CHECK(child1.next_sibling_w(STR("*[3456789]")) == child3);
|
||||
CHECK(child1.next_sibling_w(STR("?")) == xml_node());
|
||||
CHECK(child3.previous_sibling_w(STR("*[3456789]")) == xml_node());
|
||||
CHECK(child3.previous_sibling_w(STR("?")) == xml_node());
|
||||
CHECK(child3.previous_sibling_w(STR("*1")) == child1);
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_child_value, "<node><novalue/><child1>value1</child1><child2>value2<n/></child2><child3><![CDATA[value3]]></child3>value4</node>")
|
||||
{
|
||||
CHECK_STRING(xml_node().child_value(), "");
|
||||
CHECK_STRING(xml_node().child_value("n"), "");
|
||||
CHECK_STRING(xml_node().child_value_w("n"), "");
|
||||
CHECK_STRING(xml_node().child_value(), STR(""));
|
||||
CHECK_STRING(xml_node().child_value(STR("n")), STR(""));
|
||||
CHECK_STRING(xml_node().child_value_w(STR("n")), STR(""));
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK_STRING(node.child_value(), "value4");
|
||||
CHECK_STRING(node.child("child1").child_value(), "value1");
|
||||
CHECK_STRING(node.child("child2").child_value(), "value2");
|
||||
CHECK_STRING(node.child("child3").child_value(), "value3");
|
||||
CHECK_STRING(node.child_value("child3"), "value3");
|
||||
CHECK_STRING(node.child_value_w("c*[23456789]"), "value2");
|
||||
CHECK_STRING(node.child_value_w("*"), ""); // child_value(name) and child_value_w(pattern) do not continue the search if a node w/out value is found first
|
||||
CHECK_STRING(node.child_value(), STR("value4"));
|
||||
CHECK_STRING(node.child(STR("child1")).child_value(), STR("value1"));
|
||||
CHECK_STRING(node.child(STR("child2")).child_value(), STR("value2"));
|
||||
CHECK_STRING(node.child(STR("child3")).child_value(), STR("value3"));
|
||||
CHECK_STRING(node.child_value(STR("child3")), STR("value3"));
|
||||
CHECK_STRING(node.child_value_w(STR("c*[23456789]")), STR("value2"));
|
||||
CHECK_STRING(node.child_value_w(STR("*")), STR("")); // child_value(name) and child_value_w(pattern) do not continue the search if a node w/out value is found first
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_first_last_attribute, "<node attr1='0' attr2='1'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.first_attribute() == node.attribute("attr1"));
|
||||
CHECK(node.last_attribute() == node.attribute("attr2"));
|
||||
CHECK(node.first_attribute() == node.attribute(STR("attr1")));
|
||||
CHECK(node.last_attribute() == node.attribute(STR("attr2")));
|
||||
|
||||
CHECK(xml_node().first_attribute() == xml_attribute());
|
||||
CHECK(xml_node().last_attribute() == xml_attribute());
|
||||
|
@ -381,10 +386,10 @@ TEST_XML(dom_node_first_last_attribute, "<node attr1='0' attr2='1'/>")
|
|||
|
||||
TEST_XML(dom_node_first_last_child, "<node><child1/><child2/></node>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.first_child() == node.child("child1"));
|
||||
CHECK(node.last_child() == node.child("child2"));
|
||||
CHECK(node.first_child() == node.child(STR("child1")));
|
||||
CHECK(node.last_child() == node.child(STR("child2")));
|
||||
|
||||
CHECK(xml_node().first_child() == xml_node());
|
||||
CHECK(xml_node().last_child() == xml_node());
|
||||
|
@ -395,22 +400,22 @@ TEST_XML(dom_node_first_last_child, "<node><child1/><child2/></node>")
|
|||
|
||||
TEST_XML(dom_node_find_child_by_attribute, "<node><child1 attr='value1'/><child2 attr='value2'/><child2 attr='value3'/></node>")
|
||||
{
|
||||
CHECK(xml_node().find_child_by_attribute("name", "attr", "value") == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute_w("name", "attr", "value") == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute("attr", "value") == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute_w("attr", "value") == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute(STR("name"), STR("attr"), STR("value")) == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute_w(STR("name"), STR("attr"), STR("value")) == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute(STR("attr"), STR("value")) == xml_node());
|
||||
CHECK(xml_node().find_child_by_attribute_w(STR("attr"), STR("value")) == xml_node());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.find_child_by_attribute("child2", "attr", "value3") == node.last_child());
|
||||
CHECK(node.find_child_by_attribute("child2", "attr3", "value3") == xml_node());
|
||||
CHECK(node.find_child_by_attribute("attr", "value2") == node.child("child2"));
|
||||
CHECK(node.find_child_by_attribute("attr3", "value") == xml_node());
|
||||
CHECK(node.find_child_by_attribute(STR("child2"), STR("attr"), STR("value3")) == node.last_child());
|
||||
CHECK(node.find_child_by_attribute(STR("child2"), STR("attr3"), STR("value3")) == xml_node());
|
||||
CHECK(node.find_child_by_attribute(STR("attr"), STR("value2")) == node.child(STR("child2")));
|
||||
CHECK(node.find_child_by_attribute(STR("attr3"), STR("value")) == xml_node());
|
||||
|
||||
CHECK(node.find_child_by_attribute_w("*", "att?", "val*[0123456789]") == node.child("child1"));
|
||||
CHECK(node.find_child_by_attribute_w("*", "attr3", "val*[0123456789]") == xml_node());
|
||||
CHECK(node.find_child_by_attribute_w("att?", "val*[0123456789]") == node.child("child1"));
|
||||
CHECK(node.find_child_by_attribute_w("attr3", "val*[0123456789]") == xml_node());
|
||||
CHECK(node.find_child_by_attribute_w(STR("*"), STR("att?"), STR("val*[0123456789]")) == node.child(STR("child1")));
|
||||
CHECK(node.find_child_by_attribute_w(STR("*"), STR("attr3"), STR("val*[0123456789]")) == xml_node());
|
||||
CHECK(node.find_child_by_attribute_w(STR("att?"), STR("val*[0123456789]")) == node.child(STR("child1")));
|
||||
CHECK(node.find_child_by_attribute_w(STR("attr3"), STR("val*[0123456789]")) == xml_node());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_all_elements_by_name, "<node><child><child/><child/></child></node>")
|
||||
|
@ -418,31 +423,31 @@ TEST_XML(dom_node_all_elements_by_name, "<node><child><child/><child/></child></
|
|||
std::vector<xml_node> v;
|
||||
|
||||
v.clear();
|
||||
xml_node().all_elements_by_name("node", std::back_inserter(v));
|
||||
xml_node().all_elements_by_name(STR("node"), std::back_inserter(v));
|
||||
CHECK(v.empty());
|
||||
|
||||
v.clear();
|
||||
xml_node().all_elements_by_name_w("*", std::back_inserter(v));
|
||||
xml_node().all_elements_by_name_w(STR("*"), std::back_inserter(v));
|
||||
CHECK(v.empty());
|
||||
|
||||
v.clear();
|
||||
doc.all_elements_by_name("node", std::back_inserter(v));
|
||||
CHECK(v.size() == 1 && v[0] == doc.child("node"));
|
||||
doc.all_elements_by_name(STR("node"), std::back_inserter(v));
|
||||
CHECK(v.size() == 1 && v[0] == doc.child(STR("node")));
|
||||
|
||||
v.clear();
|
||||
doc.all_elements_by_name("child", std::back_inserter(v));
|
||||
doc.all_elements_by_name(STR("child"), std::back_inserter(v));
|
||||
CHECK(v.size() == 3);
|
||||
CHECK(v[0] == doc.child("node").child("child"));
|
||||
CHECK(v[1] == doc.child("node").child("child").first_child());
|
||||
CHECK(v[2] == doc.child("node").child("child").last_child());
|
||||
CHECK(v[0] == doc.child(STR("node")).child(STR("child")));
|
||||
CHECK(v[1] == doc.child(STR("node")).child(STR("child")).first_child());
|
||||
CHECK(v[2] == doc.child(STR("node")).child(STR("child")).last_child());
|
||||
|
||||
v.clear();
|
||||
doc.all_elements_by_name_w("*", std::back_inserter(v));
|
||||
doc.all_elements_by_name_w(STR("*"), std::back_inserter(v));
|
||||
CHECK(v.size() == 4);
|
||||
CHECK(v[0] == doc.child("node"));
|
||||
CHECK(v[1] == doc.child("node").child("child"));
|
||||
CHECK(v[2] == doc.child("node").child("child").first_child());
|
||||
CHECK(v[3] == doc.child("node").child("child").last_child());
|
||||
CHECK(v[0] == doc.child(STR("node")));
|
||||
CHECK(v[1] == doc.child(STR("node")).child(STR("child")));
|
||||
CHECK(v[2] == doc.child(STR("node")).child(STR("child")).first_child());
|
||||
CHECK(v[3] == doc.child(STR("node")).child(STR("child")).last_child());
|
||||
}
|
||||
|
||||
struct find_predicate_const
|
||||
|
@ -461,15 +466,20 @@ struct find_predicate_const
|
|||
|
||||
struct find_predicate_prefix
|
||||
{
|
||||
const char* prefix;
|
||||
const pugi::char_t* prefix;
|
||||
|
||||
find_predicate_prefix(const char* prefix): prefix(prefix)
|
||||
find_predicate_prefix(const pugi::char_t* prefix): prefix(prefix)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> bool operator()(const T& obj) const
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
// can't use wcsncmp here because of a bug in DMC
|
||||
return std::basic_string<pugi::char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0;
|
||||
#else
|
||||
return strncmp(obj.name(), prefix, strlen(prefix)) == 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -477,86 +487,86 @@ TEST_XML(dom_node_find_attribute, "<node attr1='0' attr2='1'/>")
|
|||
{
|
||||
CHECK(xml_node().find_attribute(find_predicate_const(true)) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(doc.find_attribute(find_predicate_const(true)) == xml_attribute());
|
||||
CHECK(node.find_attribute(find_predicate_const(true)) == node.first_attribute());
|
||||
CHECK(node.find_attribute(find_predicate_const(false)) == xml_attribute());
|
||||
CHECK(node.find_attribute(find_predicate_prefix("attr2")) == node.last_attribute());
|
||||
CHECK(node.find_attribute(find_predicate_prefix("attr")) == node.first_attribute());
|
||||
CHECK(node.find_attribute(find_predicate_prefix(STR("attr2"))) == node.last_attribute());
|
||||
CHECK(node.find_attribute(find_predicate_prefix(STR("attr"))) == node.first_attribute());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_find_child, "<node><child1/><child2/></node>")
|
||||
{
|
||||
CHECK(xml_node().find_child(find_predicate_const(true)) == xml_node());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child("node").child("child1").find_child(find_predicate_const(true)) == xml_node());
|
||||
CHECK(node.child(STR("node")).child(STR("child1")).find_child(find_predicate_const(true)) == xml_node());
|
||||
CHECK(node.find_child(find_predicate_const(true)) == node.first_child());
|
||||
CHECK(node.find_child(find_predicate_const(false)) == xml_node());
|
||||
CHECK(node.find_child(find_predicate_prefix("child2")) == node.last_child());
|
||||
CHECK(node.find_child(find_predicate_prefix("child")) == node.first_child());
|
||||
CHECK(node.find_child(find_predicate_prefix(STR("child2"))) == node.last_child());
|
||||
CHECK(node.find_child(find_predicate_prefix(STR("child"))) == node.first_child());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_find_node, "<node><child1/><child2/></node>")
|
||||
{
|
||||
CHECK(xml_node().find_node(find_predicate_const(true)) == xml_node());
|
||||
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child("node").child("child1").find_node(find_predicate_const(true)) == xml_node());
|
||||
CHECK(node.child(STR("node")).child(STR("child1")).find_node(find_predicate_const(true)) == xml_node());
|
||||
CHECK(node.find_node(find_predicate_const(true)) == node.first_child());
|
||||
CHECK(node.find_node(find_predicate_const(false)) == xml_node());
|
||||
CHECK(node.find_node(find_predicate_prefix("child2")) == node.last_child());
|
||||
CHECK(node.find_node(find_predicate_prefix("child")) == node.first_child());
|
||||
CHECK(doc.find_node(find_predicate_prefix("child")) == node.first_child());
|
||||
CHECK(doc.find_node(find_predicate_prefix("child2")) == node.last_child());
|
||||
CHECK(doc.find_node(find_predicate_prefix("child3")) == xml_node());
|
||||
CHECK(node.find_node(find_predicate_prefix(STR("child2"))) == node.last_child());
|
||||
CHECK(node.find_node(find_predicate_prefix(STR("child"))) == node.first_child());
|
||||
CHECK(doc.find_node(find_predicate_prefix(STR("child"))) == node.first_child());
|
||||
CHECK(doc.find_node(find_predicate_prefix(STR("child2"))) == node.last_child());
|
||||
CHECK(doc.find_node(find_predicate_prefix(STR("child3"))) == xml_node());
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
TEST_XML(dom_node_path, "<node><child1>text<child2/></child1></node>")
|
||||
{
|
||||
CHECK(xml_node().path() == "");
|
||||
CHECK(xml_node().path() == STR(""));
|
||||
|
||||
CHECK(doc.path() == "");
|
||||
CHECK(doc.child("node").path() == "/node");
|
||||
CHECK(doc.child("node").child("child1").path() == "/node/child1");
|
||||
CHECK(doc.child("node").child("child1").child("child2").path() == "/node/child1/child2");
|
||||
CHECK(doc.child("node").child("child1").first_child().path() == "/node/child1/");
|
||||
CHECK(doc.path() == STR(""));
|
||||
CHECK(doc.child(STR("node")).path() == STR("/node"));
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).path() == STR("/node/child1"));
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).child(STR("child2")).path() == STR("/node/child1/child2"));
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).first_child().path() == STR("/node/child1/"));
|
||||
|
||||
CHECK(doc.child("node").child("child1").path('\\') == "\\node\\child1");
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).path('\\') == STR("\\node\\child1"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></node>")
|
||||
{
|
||||
CHECK(xml_node().first_element_by_path("/") == xml_node());
|
||||
CHECK(xml_node().first_element_by_path(STR("/")) == xml_node());
|
||||
|
||||
CHECK(doc.first_element_by_path("") == doc);
|
||||
CHECK(doc.first_element_by_path("/") == doc);
|
||||
CHECK(doc.first_element_by_path(STR("")) == doc);
|
||||
CHECK(doc.first_element_by_path(STR("/")) == doc);
|
||||
|
||||
CHECK(doc.first_element_by_path("/node/") == doc.child("node"));
|
||||
CHECK(doc.first_element_by_path("node/") == doc.child("node"));
|
||||
CHECK(doc.first_element_by_path("node") == doc.child("node"));
|
||||
CHECK(doc.first_element_by_path("/node") == doc.child("node"));
|
||||
CHECK(doc.first_element_by_path(STR("/node/")) == doc.child(STR("node")));
|
||||
CHECK(doc.first_element_by_path(STR("node/")) == doc.child(STR("node")));
|
||||
CHECK(doc.first_element_by_path(STR("node")) == doc.child(STR("node")));
|
||||
CHECK(doc.first_element_by_path(STR("/node")) == doc.child(STR("node")));
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
CHECK(doc.first_element_by_path("/node/child1/child2").path() == "/node/child1/child2");
|
||||
CHECK(doc.first_element_by_path(STR("/node/child1/child2")).path() == STR("/node/child1/child2"));
|
||||
#endif
|
||||
|
||||
CHECK(doc.first_element_by_path("/node/child2") == xml_node());
|
||||
CHECK(doc.first_element_by_path(STR("/node/child2")) == xml_node());
|
||||
|
||||
CHECK(doc.first_element_by_path("\\node\\child1", '\\') == doc.child("node").child("child1"));
|
||||
CHECK(doc.first_element_by_path(STR("\\node\\child1"), '\\') == doc.child(STR("node")).child(STR("child1")));
|
||||
|
||||
CHECK(doc.child("node").first_element_by_path("..") == doc);
|
||||
CHECK(doc.child("node").first_element_by_path(".") == doc.child("node"));
|
||||
CHECK(doc.child(STR("node")).first_element_by_path(STR("..")) == doc);
|
||||
CHECK(doc.child(STR("node")).first_element_by_path(STR(".")) == doc.child(STR("node")));
|
||||
}
|
||||
|
||||
struct test_walker: xml_tree_walker
|
||||
{
|
||||
std::string log;
|
||||
std::basic_string<pugi::char_t> log;
|
||||
unsigned int call_count;
|
||||
unsigned int stop_count;
|
||||
|
||||
|
@ -564,32 +574,53 @@ struct test_walker: xml_tree_walker
|
|||
{
|
||||
}
|
||||
|
||||
std::basic_string<pugi::char_t> depthstr() const
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "%d", depth());
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wchar_t wbuf[32];
|
||||
std::copy(buf, buf + strlen(buf) + 1, wbuf);
|
||||
|
||||
return std::basic_string<pugi::char_t>(wbuf);
|
||||
#else
|
||||
return std::basic_string<pugi::char_t>(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool begin(xml_node& node)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "|%d <%s=%s", depth(), node.name(), node.value());
|
||||
|
||||
log += buffer;
|
||||
log += STR("|");
|
||||
log += depthstr();
|
||||
log += STR(" <");
|
||||
log += node.name();
|
||||
log += STR("=");
|
||||
log += node.value();
|
||||
|
||||
return ++call_count != stop_count && xml_tree_walker::begin(node);
|
||||
}
|
||||
|
||||
virtual bool for_each(xml_node& node)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "|%d !%s=%s", depth(), node.name(), node.value());
|
||||
|
||||
log += buffer;
|
||||
log += STR("|");
|
||||
log += depthstr();
|
||||
log += STR(" !");
|
||||
log += node.name();
|
||||
log += STR("=");
|
||||
log += node.value();
|
||||
|
||||
return ++call_count != stop_count && xml_tree_walker::end(node);
|
||||
}
|
||||
|
||||
virtual bool end(xml_node& node)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "|%d >%s=%s", depth(), node.name(), node.value());
|
||||
|
||||
log += buffer;
|
||||
log += STR("|");
|
||||
log += depthstr();
|
||||
log += STR(" >");
|
||||
log += node.name();
|
||||
log += STR("=");
|
||||
log += node.value();
|
||||
|
||||
return ++call_count != stop_count;
|
||||
}
|
||||
|
@ -602,7 +633,7 @@ TEST_XML(dom_node_traverse, "<node><child>text</child></node>")
|
|||
CHECK(doc.traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 5);
|
||||
CHECK(walker.log == "|-1 <=|0 !node=|1 !child=|2 !=text|-1 >=");
|
||||
CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|2 !=text|-1 >="));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_traverse_siblings, "<node><child/><child>text</child><child/></node>")
|
||||
|
@ -612,7 +643,7 @@ TEST_XML(dom_node_traverse_siblings, "<node><child/><child>text</child><child/><
|
|||
CHECK(doc.traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 7);
|
||||
CHECK(walker.log == "|-1 <=|0 !node=|1 !child=|1 !child=|2 !=text|1 !child=|-1 >=");
|
||||
CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|1 !child=|2 !=text|1 !child=|-1 >="));
|
||||
}
|
||||
|
||||
TEST(dom_node_traverse_empty)
|
||||
|
@ -622,17 +653,17 @@ TEST(dom_node_traverse_empty)
|
|||
CHECK(xml_node().traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 2);
|
||||
CHECK(walker.log == "|-1 <=|-1 >=");
|
||||
CHECK(walker.log == STR("|-1 <=|-1 >="));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_traverse_child, "<node><child>text</child></node>")
|
||||
{
|
||||
test_walker walker;
|
||||
|
||||
CHECK(doc.child("node").traverse(walker));
|
||||
CHECK(doc.child(STR("node")).traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 4);
|
||||
CHECK(walker.log == "|-1 <node=|0 !child=|1 !=text|-1 >node=");
|
||||
CHECK(walker.log == STR("|-1 <node=|0 !child=|1 !=text|-1 >node="));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_traverse_stop_begin, "<node><child>text</child></node>")
|
||||
|
@ -642,7 +673,7 @@ TEST_XML(dom_node_traverse_stop_begin, "<node><child>text</child></node>")
|
|||
CHECK(!doc.traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 1);
|
||||
CHECK(walker.log == "|-1 <=");
|
||||
CHECK(walker.log == STR("|-1 <="));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_traverse_stop_for_each, "<node><child>text</child></node>")
|
||||
|
@ -652,7 +683,7 @@ TEST_XML(dom_node_traverse_stop_for_each, "<node><child>text</child></node>")
|
|||
CHECK(!doc.traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 3);
|
||||
CHECK(walker.log == "|-1 <=|0 !node=|1 !child=");
|
||||
CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child="));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_traverse_stop_end, "<node><child>text</child></node>")
|
||||
|
@ -662,7 +693,7 @@ TEST_XML(dom_node_traverse_stop_end, "<node><child>text</child></node>")
|
|||
CHECK(!doc.traverse(walker));
|
||||
|
||||
CHECK(walker.call_count == 5);
|
||||
CHECK(walker.log == "|-1 <=|0 !node=|1 !child=|2 !=text|-1 >=");
|
||||
CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|2 !=text|-1 >="));
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(dom_offset_debug, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration)
|
||||
|
@ -677,7 +708,7 @@ TEST_XML_FLAGS(dom_offset_debug, "<?xml?><?pi?><!--comment--><node>pcdata<![CDAT
|
|||
CHECK((it++)->offset_debug() == 17);
|
||||
CHECK((it++)->offset_debug() == 28);
|
||||
|
||||
xml_node_iterator cit = doc.child("node").begin();
|
||||
xml_node_iterator cit = doc.child(STR("node")).begin();
|
||||
|
||||
CHECK((cit++)->offset_debug() == 33);
|
||||
CHECK((cit++)->offset_debug() == 48);
|
||||
|
@ -685,24 +716,24 @@ TEST_XML_FLAGS(dom_offset_debug, "<?xml?><?pi?><!--comment--><node>pcdata<![CDAT
|
|||
|
||||
TEST_XML(dom_node_wildcard_cset, "<node c='1'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.attribute_w("[A-Z]").as_int() == 0);
|
||||
CHECK(node.attribute_w("[a-z]").as_int() == 1);
|
||||
CHECK(node.attribute_w("[A-z]").as_int() == 1);
|
||||
CHECK(node.attribute_w("[z-a]").as_int() == 0);
|
||||
CHECK(node.attribute_w("[a-zA-Z]").as_int() == 1);
|
||||
CHECK(node.attribute_w("[!A-Z]").as_int() == 1);
|
||||
CHECK(node.attribute_w("[!A-Za-z]").as_int() == 0);
|
||||
CHECK(node.attribute_w(STR("[A-Z]")).as_int() == 0);
|
||||
CHECK(node.attribute_w(STR("[a-z]")).as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("[A-z]")).as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("[z-a]")).as_int() == 0);
|
||||
CHECK(node.attribute_w(STR("[a-zA-Z]")).as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("[!A-Z]")).as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("[!A-Za-z]")).as_int() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_wildcard_star, "<node cd='1'/>")
|
||||
{
|
||||
xml_node node = doc.child("node");
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.attribute_w("*").as_int() == 1);
|
||||
CHECK(node.attribute_w("?d*").as_int() == 1);
|
||||
CHECK(node.attribute_w("?c*").as_int() == 0);
|
||||
CHECK(node.attribute_w("*?*c*").as_int() == 0);
|
||||
CHECK(node.attribute_w("*?*d*").as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("*")).as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("?d*")).as_int() == 1);
|
||||
CHECK(node.attribute_w(STR("?c*")).as_int() == 0);
|
||||
CHECK(node.attribute_w(STR("*?*c*")).as_int() == 0);
|
||||
CHECK(node.attribute_w(STR("*?*d*")).as_int() == 1);
|
||||
}
|
||||
|
|
3
tests/test_header_guard.cpp
Normal file
3
tests/test_header_guard.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
3
tests/test_header_iosfwd_1.cpp
Normal file
3
tests/test_header_iosfwd_1.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests compatibility with iosfwd
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <iosfwd>
|
3
tests/test_header_iosfwd_2.cpp
Normal file
3
tests/test_header_iosfwd_2.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests compatibility with iosfwd
|
||||
#include <iosfwd>
|
||||
#include "../src/pugixml.hpp"
|
3
tests/test_header_iostream_1.cpp
Normal file
3
tests/test_header_iostream_1.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests compatibility with iostream
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <iostream>
|
3
tests/test_header_iostream_2.cpp
Normal file
3
tests/test_header_iostream_2.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests compatibility with iostream
|
||||
#include <iostream>
|
||||
#include "../src/pugixml.hpp"
|
3
tests/test_header_string_1.cpp
Normal file
3
tests/test_header_string_1.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests compatibility with string
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <string>
|
3
tests/test_header_string_2.cpp
Normal file
3
tests/test_header_string_2.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Tests compatibility with string
|
||||
#include <string>
|
||||
#include "../src/pugixml.hpp"
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
char buffer[8];
|
||||
pugi::char_t buffer[8];
|
||||
int allocate_count = 0;
|
||||
int deallocate_count = 0;
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
CHECK(size == 8);
|
||||
CHECK(size == sizeof(pugi::char_t) * 8);
|
||||
++allocate_count;
|
||||
return buffer;
|
||||
}
|
||||
|
@ -32,23 +32,23 @@ TEST(custom_memory_management)
|
|||
{
|
||||
// parse document
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node/>"));
|
||||
CHECK(doc.load(STR("<node />")));
|
||||
|
||||
CHECK(allocate_count == 1);
|
||||
CHECK(deallocate_count == 0);
|
||||
CHECK_STRING(buffer, "<node\0>");
|
||||
CHECK_STRING(buffer, STR("<node"));
|
||||
|
||||
// modify document
|
||||
doc.child("node").set_name("foobars");
|
||||
doc.child(STR("node")).set_name(STR("foobars"));
|
||||
|
||||
CHECK(allocate_count == 2);
|
||||
CHECK(deallocate_count == 0);
|
||||
CHECK_STRING(buffer, "foobars");
|
||||
CHECK_STRING(buffer, STR("foobars"));
|
||||
}
|
||||
|
||||
CHECK(allocate_count == 2);
|
||||
CHECK(deallocate_count == 2);
|
||||
CHECK_STRING(buffer, "foobars");
|
||||
CHECK_STRING(buffer, STR("foobars"));
|
||||
|
||||
// restore old functions
|
||||
set_memory_management_functions(old_allocate, old_deallocate);
|
||||
|
|
|
@ -3,25 +3,25 @@
|
|||
TEST(parse_pi_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<?pi?><?pi value?>", parse_minimal));
|
||||
CHECK(doc.load(STR("<?pi?><?pi value?>"), parse_minimal));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(parse_pi_parse)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<?pi1?><?pi2 value?>", parse_minimal | parse_pi));
|
||||
CHECK(doc.load(STR("<?pi1?><?pi2 value?>"), parse_minimal | parse_pi));
|
||||
|
||||
xml_node pi1 = doc.first_child();
|
||||
xml_node pi2 = doc.last_child();
|
||||
|
||||
CHECK(pi1 != pi2);
|
||||
CHECK(pi1.type() == node_pi);
|
||||
CHECK_STRING(pi1.name(), "pi1");
|
||||
CHECK_STRING(pi1.value(), "");
|
||||
CHECK_STRING(pi1.name(), STR("pi1"));
|
||||
CHECK_STRING(pi1.value(), STR(""));
|
||||
CHECK(pi2.type() == node_pi);
|
||||
CHECK_STRING(pi2.name(), "pi2");
|
||||
CHECK_STRING(pi2.value(), "value");
|
||||
CHECK_STRING(pi2.name(), STR("pi2"));
|
||||
CHECK_STRING(pi2.value(), STR("value"));
|
||||
}
|
||||
|
||||
TEST(parse_pi_error)
|
||||
|
@ -34,56 +34,69 @@ TEST(parse_pi_error)
|
|||
{
|
||||
unsigned int flags = flag_sets[i];
|
||||
|
||||
CHECK(doc.load("<?", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?#?>", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?name", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?name>", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?name ?", flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<??"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?>"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?#?>"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name>"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name ?"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name?"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name? "), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name? "), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name "), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name "), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name "), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name value"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name value "), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?name value "), flags).status == status_bad_pi);
|
||||
}
|
||||
|
||||
CHECK(doc.load(STR("<?xx#?>"), parse_minimal | parse_pi).status == status_bad_pi);
|
||||
}
|
||||
|
||||
TEST(parse_comments_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<!----><!--value-->", parse_minimal));
|
||||
CHECK(doc.load(STR("<!----><!--value-->"), parse_minimal));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(parse_comments_parse)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<!----><!--value-->", parse_minimal | parse_comments));
|
||||
CHECK(doc.load(STR("<!----><!--value-->"), parse_minimal | parse_comments));
|
||||
|
||||
xml_node c1 = doc.first_child();
|
||||
xml_node c2 = doc.last_child();
|
||||
|
||||
CHECK(c1 != c2);
|
||||
CHECK(c1.type() == node_comment);
|
||||
CHECK_STRING(c1.name(), "");
|
||||
CHECK_STRING(c1.value(), "");
|
||||
CHECK_STRING(c1.name(), STR(""));
|
||||
CHECK_STRING(c1.value(), STR(""));
|
||||
CHECK(c2.type() == node_comment);
|
||||
CHECK_STRING(c2.name(), "");
|
||||
CHECK_STRING(c2.value(), "value");
|
||||
CHECK_STRING(c2.name(), STR(""));
|
||||
CHECK_STRING(c2.value(), STR("value"));
|
||||
}
|
||||
|
||||
TEST(parse_comments_parse_no_eol)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->", parse_minimal | parse_comments));
|
||||
CHECK(doc.load(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_minimal | parse_comments));
|
||||
|
||||
xml_node c = doc.first_child();
|
||||
CHECK(c.type() == node_comment);
|
||||
CHECK_STRING(c.value(), "\r\rval1\rval2\r\nval3\nval4\r\r");
|
||||
CHECK_STRING(c.value(), STR("\r\rval1\rval2\r\nval3\nval4\r\r"));
|
||||
}
|
||||
|
||||
TEST(parse_comments_parse_eol)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->", parse_minimal | parse_comments | parse_eol));
|
||||
CHECK(doc.load(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_minimal | parse_comments | parse_eol));
|
||||
|
||||
xml_node c = doc.first_child();
|
||||
CHECK(c.type() == node_comment);
|
||||
CHECK_STRING(c.value(), "\n\nval1\nval2\nval3\nval4\n\n");
|
||||
CHECK_STRING(c.value(), STR("\n\nval1\nval2\nval3\nval4\n\n"));
|
||||
}
|
||||
|
||||
TEST(parse_comments_error)
|
||||
|
@ -96,57 +109,57 @@ TEST(parse_comments_error)
|
|||
{
|
||||
unsigned int flags = flag_sets[i];
|
||||
|
||||
CHECK(doc.load("<!-", flags).status == status_bad_comment);
|
||||
CHECK(doc.load("<!--", flags).status == status_bad_comment);
|
||||
CHECK(doc.load("<!--v", flags).status == status_bad_comment);
|
||||
CHECK(doc.load("<!-->", flags).status == status_bad_comment);
|
||||
CHECK(doc.load("<!--->", flags).status == status_bad_comment);
|
||||
CHECK(doc.load("<!-- <!-- --><!- -->", flags).status == status_bad_comment);
|
||||
CHECK(doc.load(STR("<!-"), flags).status == status_bad_comment);
|
||||
CHECK(doc.load(STR("<!--"), flags).status == status_bad_comment);
|
||||
CHECK(doc.load(STR("<!--v"), flags).status == status_bad_comment);
|
||||
CHECK(doc.load(STR("<!-->"), flags).status == status_bad_comment);
|
||||
CHECK(doc.load(STR("<!--->"), flags).status == status_bad_comment);
|
||||
CHECK(doc.load(STR("<!-- <!-- --><!- -->"), flags).status == status_bad_comment);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_cdata_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<![CDATA[]]><![CDATA[value]]>", parse_minimal));
|
||||
CHECK(doc.load(STR("<![CDATA[]]><![CDATA[value]]>"), parse_minimal));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(parse_cdata_parse)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<![CDATA[]]><![CDATA[value]]>", parse_minimal | parse_cdata));
|
||||
CHECK(doc.load(STR("<![CDATA[]]><![CDATA[value]]>"), parse_minimal | parse_cdata));
|
||||
|
||||
xml_node c1 = doc.first_child();
|
||||
xml_node c2 = doc.last_child();
|
||||
|
||||
CHECK(c1 != c2);
|
||||
CHECK(c1.type() == node_cdata);
|
||||
CHECK_STRING(c1.name(), "");
|
||||
CHECK_STRING(c1.value(), "");
|
||||
CHECK_STRING(c1.name(), STR(""));
|
||||
CHECK_STRING(c1.value(), STR(""));
|
||||
CHECK(c2.type() == node_cdata);
|
||||
CHECK_STRING(c2.name(), "");
|
||||
CHECK_STRING(c2.value(), "value");
|
||||
CHECK_STRING(c2.name(), STR(""));
|
||||
CHECK_STRING(c2.value(), STR("value"));
|
||||
}
|
||||
|
||||
TEST(parse_cdata_parse_no_eol)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>", parse_minimal | parse_cdata));
|
||||
CHECK(doc.load(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_minimal | parse_cdata));
|
||||
|
||||
xml_node c = doc.first_child();
|
||||
CHECK(c.type() == node_cdata);
|
||||
CHECK_STRING(c.value(), "\r\rval1\rval2\r\nval3\nval4\r\r");
|
||||
CHECK_STRING(c.value(), STR("\r\rval1\rval2\r\nval3\nval4\r\r"));
|
||||
}
|
||||
|
||||
TEST(parse_cdata_parse_eol)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>", parse_minimal | parse_cdata | parse_eol));
|
||||
CHECK(doc.load(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_minimal | parse_cdata | parse_eol));
|
||||
|
||||
xml_node c = doc.first_child();
|
||||
CHECK(c.type() == node_cdata);
|
||||
CHECK_STRING(c.value(), "\n\nval1\nval2\nval3\nval4\n\n");
|
||||
CHECK_STRING(c.value(), STR("\n\nval1\nval2\nval3\nval4\n\n"));
|
||||
}
|
||||
|
||||
TEST(parse_cdata_error)
|
||||
|
@ -159,28 +172,31 @@ TEST(parse_cdata_error)
|
|||
{
|
||||
unsigned int flags = flag_sets[i];
|
||||
|
||||
CHECK(doc.load("<![", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![C", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CD", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDA", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDAT", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDATA", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDATA[", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDATA[]", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDATA[>", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load("<![CDATA[ <![CDATA[]]><![CDATA ]]>", flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<!["), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![C"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CD"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDA"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDAT"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA["), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA[]"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA[data"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA[data]"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA[data]]"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA[>"), flags).status == status_bad_cdata);
|
||||
CHECK(doc.load(STR("<![CDATA[ <![CDATA[]]><![CDATA ]]>"), flags).status == status_bad_cdata);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_ws_pcdata_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load(" ", parse_minimal));
|
||||
CHECK(doc.load(STR(" "), parse_minimal));
|
||||
CHECK(!doc.first_child());
|
||||
|
||||
CHECK(doc.load("<root> <node> </node> </root>", parse_minimal));
|
||||
CHECK(doc.load(STR("<root> <node> </node> </root>"), parse_minimal));
|
||||
|
||||
xml_node root = doc.child("root");
|
||||
xml_node root = doc.child(STR("root"));
|
||||
|
||||
CHECK(root.first_child() == root.last_child());
|
||||
CHECK(!root.first_child().first_child());
|
||||
|
@ -189,9 +205,9 @@ TEST(parse_ws_pcdata_skip)
|
|||
TEST(parse_ws_pcdata_parse)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<root> <node> </node> </root>", parse_minimal | parse_ws_pcdata));
|
||||
CHECK(doc.load(STR("<root> <node> </node> </root>"), parse_minimal | parse_ws_pcdata));
|
||||
|
||||
xml_node root = doc.child("root");
|
||||
xml_node root = doc.child(STR("root"));
|
||||
|
||||
xml_node c1 = root.first_child();
|
||||
xml_node c2 = c1.next_sibling();
|
||||
|
@ -200,35 +216,35 @@ TEST(parse_ws_pcdata_parse)
|
|||
CHECK(c3 == root.last_child());
|
||||
|
||||
CHECK(c1.type() == node_pcdata);
|
||||
CHECK_STRING(c1.value(), " ");
|
||||
CHECK_STRING(c1.value(), STR(" "));
|
||||
CHECK(c3.type() == node_pcdata);
|
||||
CHECK_STRING(c3.value(), " ");
|
||||
CHECK_STRING(c3.value(), STR(" "));
|
||||
|
||||
CHECK(c2.first_child() == c2.last_child());
|
||||
CHECK(c2.first_child().type() == node_pcdata);
|
||||
CHECK_STRING(c2.first_child().value(), " ");
|
||||
CHECK_STRING(c2.first_child().value(), STR(" "));
|
||||
}
|
||||
|
||||
TEST(parse_pcdata_no_eol)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>", parse_minimal));
|
||||
CHECK(doc.load(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal));
|
||||
|
||||
CHECK_STRING(doc.child_value("root"), "\r\rval1\rval2\r\nval3\nval4\r\r");
|
||||
CHECK_STRING(doc.child_value(STR("root")), STR("\r\rval1\rval2\r\nval3\nval4\r\r"));
|
||||
}
|
||||
|
||||
TEST(parse_pcdata_eol)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>", parse_minimal | parse_eol));
|
||||
CHECK(doc.load(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal | parse_eol));
|
||||
|
||||
CHECK_STRING(doc.child_value("root"), "\n\nval1\nval2\nval3\nval4\n\n");
|
||||
CHECK_STRING(doc.child_value(STR("root")), STR("\n\nval1\nval2\nval3\nval4\n\n"));
|
||||
}
|
||||
|
||||
TEST(parse_pcdata_skip_ext)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("pre<root/>post", parse_minimal));
|
||||
CHECK(doc.load(STR("pre<root/>post"), parse_minimal));
|
||||
CHECK(doc.first_child() == doc.last_child());
|
||||
CHECK(doc.first_child().type() == node_element);
|
||||
}
|
||||
|
@ -236,99 +252,109 @@ TEST(parse_pcdata_skip_ext)
|
|||
TEST(parse_pcdata_error)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<root>pcdata", parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<root>pcdata"), parse_minimal).status == status_end_element_mismatch);
|
||||
}
|
||||
|
||||
TEST(parse_escapes_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id='<>&'"'><>&'"</node>", parse_minimal));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), "<>&'"");
|
||||
CHECK(doc.load(STR("<node id='<>&'"'><>&'"</node>"), parse_minimal));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("<>&'""));
|
||||
}
|
||||
|
||||
TEST(parse_escapes_parse)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id='<>&'"'><>&'"</node>", parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value("node"), "<>&'\"");
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), "<>&'\"");
|
||||
CHECK(doc.load(STR("<node id='<>&'"'><>&'"</node>"), parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value(STR("node")), STR("<>&'\""));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("<>&'\""));
|
||||
}
|
||||
|
||||
TEST(parse_escapes_code)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node>  </node>", parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value("node"), "\01 ");
|
||||
CHECK(doc.load(STR("<node>  </node>"), parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value(STR("node")), STR("\01 "));
|
||||
}
|
||||
|
||||
TEST(parse_escapes_unicode)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node>γγ</node>", parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value("node"), "\xce\xb3\xce\xb3");
|
||||
CHECK(doc.load(STR("<node>γγ𤭢</node>"), parse_minimal | parse_escapes));
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
const pugi::char_t* v = doc.child_value(STR("node"));
|
||||
|
||||
unsigned int v2 = v[2];
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
|
||||
CHECK(v[0] == 0x3b3 && v[1] == 0x3b3 && (wcharsize == 2 ? v[2] == 0xd852 && v[3] == 0xdf62 : v2 == 0x24b62));
|
||||
#else
|
||||
CHECK_STRING(doc.child_value(STR("node")), "\xce\xb3\xce\xb3\xf0\xa4\xad\xa2");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(parse_escapes_error)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node>g;&#ab;"</node>", parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value("node"), "g;&#ab;"");
|
||||
CHECK(doc.load(STR("<node>g;&#ab;"</node>"), parse_minimal | parse_escapes));
|
||||
CHECK_STRING(doc.child_value(STR("node")), STR("g;&#ab;""));
|
||||
|
||||
CHECK(!doc.load("<node id='"));
|
||||
CHECK(!doc.load("<node id='&g"));
|
||||
CHECK(!doc.load("<node id='>"));
|
||||
CHECK(!doc.load("<node id='&l"));
|
||||
CHECK(!doc.load("<node id='<"));
|
||||
CHECK(!doc.load("<node id='&a"));
|
||||
CHECK(!doc.load("<node id='&"));
|
||||
CHECK(!doc.load("<node id='&apos"));
|
||||
CHECK(!doc.load(STR("<node id='")));
|
||||
CHECK(!doc.load(STR("<node id='&g")));
|
||||
CHECK(!doc.load(STR("<node id='>")));
|
||||
CHECK(!doc.load(STR("<node id='&l")));
|
||||
CHECK(!doc.load(STR("<node id='<")));
|
||||
CHECK(!doc.load(STR("<node id='&a")));
|
||||
CHECK(!doc.load(STR("<node id='&")));
|
||||
CHECK(!doc.load(STR("<node id='&apos")));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_spaces)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id1='v1' id2 ='v2' id3= 'v3' id4 = 'v4' id5 \n\r\t = \r\t\n 'v5' />", parse_minimal));
|
||||
CHECK_STRING(doc.child("node").attribute("id1").value(), "v1");
|
||||
CHECK_STRING(doc.child("node").attribute("id2").value(), "v2");
|
||||
CHECK_STRING(doc.child("node").attribute("id3").value(), "v3");
|
||||
CHECK_STRING(doc.child("node").attribute("id4").value(), "v4");
|
||||
CHECK_STRING(doc.child("node").attribute("id5").value(), "v5");
|
||||
CHECK(doc.load(STR("<node id1='v1' id2 ='v2' id3= 'v3' id4 = 'v4' id5 \n\r\t = \r\t\n 'v5' />"), parse_minimal));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("v1"));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("v2"));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id3")).value(), STR("v3"));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id4")).value(), STR("v4"));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id5")).value(), STR("v5"));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_quot)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id1='v1' id2=\"v2\"/>", parse_minimal));
|
||||
CHECK_STRING(doc.child("node").attribute("id1").value(), "v1");
|
||||
CHECK_STRING(doc.child("node").attribute("id2").value(), "v2");
|
||||
CHECK(doc.load(STR("<node id1='v1' id2=\"v2\"/>"), parse_minimal));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("v1"));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("v2"));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_no_eol_no_wconv)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>", parse_minimal));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), " \t\r\rval1 \rval2\r\nval3\nval4\r\r");
|
||||
CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" \t\r\rval1 \rval2\r\nval3\nval4\r\r"));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_eol_no_wconv)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>", parse_minimal | parse_eol));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), " \t\n\nval1 \nval2\nval3\nval4\n\n");
|
||||
CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" \t\n\nval1 \nval2\nval3\nval4\n\n"));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_no_eol_wconv)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>", parse_minimal | parse_wconv_attribute));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), " val1 val2 val3 val4 ");
|
||||
CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_wconv_attribute));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" val1 val2 val3 val4 "));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_eol_wconv)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>", parse_minimal | parse_eol | parse_wconv_attribute));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), " val1 val2 val3 val4 ");
|
||||
CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol | parse_wconv_attribute));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" val1 val2 val3 val4 "));
|
||||
}
|
||||
|
||||
TEST(parse_attribute_wnorm)
|
||||
|
@ -339,8 +365,8 @@ TEST(parse_attribute_wnorm)
|
|||
for (int wconv = 0; wconv < 2; ++wconv)
|
||||
{
|
||||
unsigned int flags = parse_minimal | parse_wnorm_attribute | (eol ? parse_eol : 0) | (wconv ? parse_wconv_attribute : 0);
|
||||
CHECK(doc.load("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>", flags));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), "val1 val2 val3 val4");
|
||||
CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), flags));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("val1 val2 val3 val4"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,80 +386,111 @@ TEST(parse_attribute_variations)
|
|||
flags |= (wconv ? parse_wconv_attribute : 0);
|
||||
flags |= (escapes ? parse_escapes : 0);
|
||||
|
||||
CHECK(doc.load("<node id='1'/>", flags));
|
||||
CHECK_STRING(doc.child("node").attribute("id").value(), "1");
|
||||
CHECK(doc.load(STR("<node id='1'/>"), flags));
|
||||
CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("1"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_attribute_error)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node id/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node id=/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node id='/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node id=\"/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node id=\"'/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node id='\"/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node id='\"/>", parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load("<node #/>", parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load("<node#/>", parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node id"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id "), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id "), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id "), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id/"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id?/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id=/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id='/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id=\"/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id=\"'/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<node #/>"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node#/>"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node id1='1'id2='2'/>"), parse_minimal).status == status_bad_attribute);
|
||||
}
|
||||
|
||||
TEST(parse_tag_single)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node/><node /><node\n/>", parse_minimal));
|
||||
CHECK_NODE(doc, "<node /><node /><node />");
|
||||
CHECK(doc.load(STR("<node/><node /><node\n/>"), parse_minimal));
|
||||
CHECK_NODE(doc, STR("<node /><node /><node />"));
|
||||
}
|
||||
|
||||
TEST(parse_tag_hierarchy)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<node><n1><n2/></n1><n3><n4><n5></n5></n4></n3 \r\n></node>", parse_minimal));
|
||||
CHECK_NODE(doc, "<node><n1><n2 /></n1><n3><n4><n5 /></n4></n3></node>");
|
||||
CHECK(doc.load(STR("<node><n1><n2/></n1><n3><n4><n5></n5></n4></n3 \r\n></node>"), parse_minimal));
|
||||
CHECK_NODE(doc, STR("<node><n1><n2 /></n1><n3><n4><n5 /></n4></n3></node>"));
|
||||
}
|
||||
|
||||
TEST(parse_tag_error)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<", parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load("<!", parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load("<!D", parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load("<#", parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load("<node#", parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load("<node", parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load("<node/", parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load("<node/ >", parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load("</ node>", parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load("</node", parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load("</node ", parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load("<node></ node>", parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load("<node></node", parse_minimal).status == status_bad_end_element);
|
||||
CHECK(doc.load("<node></node ", parse_minimal).status == status_bad_end_element);
|
||||
CHECK(doc.load("<node></nodes>", parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<"), parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load(STR("<!"), parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load(STR("<!D"), parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load(STR("<#"), parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load(STR("<node#"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node/"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node /"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node / "), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node / >"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("<node/ >"), parse_minimal).status == status_bad_start_element);
|
||||
CHECK(doc.load(STR("</ node>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("</node"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("</node "), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<node></ node>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<node></node"), parse_minimal).status == status_bad_end_element);
|
||||
CHECK(doc.load(STR("<node></node "), parse_minimal).status == status_bad_end_element);
|
||||
CHECK(doc.load(STR("<node></nodes>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<node>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<node/><"), parse_minimal).status == status_unrecognized_tag);
|
||||
CHECK(doc.load(STR("<node attr='value'>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("</></node>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("</node>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("</>"), parse_minimal).status == status_end_element_mismatch);
|
||||
CHECK(doc.load(STR("<node></node v>"), parse_minimal).status == status_bad_end_element);
|
||||
}
|
||||
|
||||
TEST(parse_declaration_cases)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load(STR("<?xml?><?xmL?><?xMl?><?xML?><?Xml?><?XmL?><?XMl?><?XML?>"), parse_minimal | parse_pi));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(parse_declaration_attr_cases)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load(STR("<?xml ?><?xmL ?><?xMl ?><?xML ?><?Xml ?><?XmL ?><?XMl ?><?XML ?>"), parse_minimal | parse_pi));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(parse_declaration_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<?xml?><?xml version='1.0'?>", parse_minimal));
|
||||
CHECK(doc.load(STR("<?xml?><?xml version='1.0'?>"), parse_minimal));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(parse_declaration_parse)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<?xml?><?xml version='1.0'?>", parse_minimal | parse_declaration));
|
||||
CHECK(doc.load(STR("<?xml?><?xml version='1.0'?>"), parse_minimal | parse_declaration));
|
||||
|
||||
xml_node d1 = doc.first_child();
|
||||
xml_node d2 = doc.last_child();
|
||||
|
||||
CHECK(d1 != d2);
|
||||
CHECK(d1.type() == node_declaration);
|
||||
CHECK_STRING(d1.name(), "xml");
|
||||
CHECK_STRING(d1.name(), STR("xml"));
|
||||
CHECK(d2.type() == node_declaration);
|
||||
CHECK_STRING(d2.name(), "xml");
|
||||
CHECK_STRING(d2.attribute("version").value(), "1.0");
|
||||
CHECK_STRING(d2.name(), STR("xml"));
|
||||
CHECK_STRING(d2.attribute(STR("version")).value(), STR("1.0"));
|
||||
}
|
||||
|
||||
TEST(parse_declaration_error)
|
||||
|
@ -446,38 +503,46 @@ TEST(parse_declaration_error)
|
|||
{
|
||||
unsigned int flags = flag_sets[i];
|
||||
|
||||
CHECK(doc.load("<?xml", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?xml?", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?xml>", flags).status == status_bad_pi);
|
||||
CHECK(doc.load("<?xml version='1>", flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?xml"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?xml?"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?xml>"), flags).status == status_bad_pi);
|
||||
CHECK(doc.load(STR("<?xml version='1>"), flags).status == status_bad_pi);
|
||||
}
|
||||
|
||||
CHECK(doc.load("<?xml version='1?>", parse_minimal | parse_declaration).status == status_bad_attribute);
|
||||
CHECK(doc.load(STR("<?xml version='1?>"), parse_minimal | parse_declaration).status == status_bad_attribute);
|
||||
}
|
||||
|
||||
TEST(parse_doctype_skip)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<!DOCTYPE doc>") && !doc.first_child());
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM 'foo'>") && !doc.first_child());
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM \"foo\">") && !doc.first_child());
|
||||
CHECK(doc.load("<!DOCTYPE doc PUBLIC \"foo\" 'bar'>") && !doc.first_child());
|
||||
CHECK(doc.load("<!DOCTYPE doc PUBLIC \"foo'\">") && !doc.first_child());
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>]>") && !doc.first_child());
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc>")) && !doc.first_child());
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo'>")) && !doc.first_child());
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM \"foo\">")) && !doc.first_child());
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc PUBLIC \"foo\" 'bar'>")) && !doc.first_child());
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc PUBLIC \"foo'\">")) && !doc.first_child());
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>]>")) && !doc.first_child());
|
||||
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>]><node/>"));
|
||||
CHECK_NODE(doc, "<node />");
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>]><node/>")));
|
||||
CHECK_NODE(doc, STR("<node />"));
|
||||
}
|
||||
|
||||
TEST(parse_doctype_error)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load("<!DOCTYPE").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM 'foo").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM \"foo").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc PUBLIC \"foo\" 'bar").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc PUBLIC \"foo'\"").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY").status == status_bad_doctype);
|
||||
CHECK(doc.load("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>").status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM \"foo")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc PUBLIC \"foo\" 'bar")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc PUBLIC \"foo'\"")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>]")).status == status_bad_doctype);
|
||||
CHECK(doc.load(STR("<!DOCTYPE doc SYSTEM 'foo' [<!ELEMENT foo 'ANY'>] ")).status == status_bad_doctype);
|
||||
}
|
||||
|
||||
TEST(parse_empty)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load(STR("")) && !doc.first_child());
|
||||
}
|
||||
|
|
|
@ -1,39 +1,80 @@
|
|||
#ifndef PUGIXML_NO_STL
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
// letters taken from http://www.utf8-chartable.de/
|
||||
|
||||
#ifdef __DMC__
|
||||
#define U_LITERALS // DMC does not understand \x01234 (it parses first three digits), but understands \u01234
|
||||
#endif
|
||||
|
||||
inline wchar_t wchar_cast(unsigned int value)
|
||||
TEST(as_wide_empty)
|
||||
{
|
||||
return static_cast<wchar_t>(value); // to avoid C4310 on MSVC
|
||||
CHECK(as_wide("") == L"");
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
TEST(as_utf16)
|
||||
TEST(as_wide_valid_basic)
|
||||
{
|
||||
// valid 1-byte, 2-byte and 3-byte inputs
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf16("?\xd0\x80\xe2\x80\xbd") == L"?\u0400\u203D");
|
||||
CHECK(as_wide("?\xd0\x80\xe2\x80\xbd") == L"?\u0400\u203D");
|
||||
#else
|
||||
CHECK(as_utf16("?\xd0\x80\xe2\x80\xbd") == L"?\x0400\x203D");
|
||||
CHECK(as_wide("?\xd0\x80\xe2\x80\xbd") == L"?\x0400\x203D");
|
||||
#endif
|
||||
|
||||
// invalid 1-byte input
|
||||
CHECK(as_utf16("\xb0") == L" ");
|
||||
|
||||
// valid 4-byte input
|
||||
std::wstring b4 = as_utf16("\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
CHECK(b4.size() == 3 && b4[0] == wchar_cast(0x97624) && b4[1] == L' ' && b4[2] == wchar_cast(0x1003ff));
|
||||
|
||||
// invalid 5-byte input
|
||||
std::wstring b5 = as_utf16("\xf8\nbcd");
|
||||
CHECK(b5 == L" \nbcd");
|
||||
}
|
||||
|
||||
TEST(as_utf8)
|
||||
TEST(as_wide_valid_astral)
|
||||
{
|
||||
// valid 4-byte input
|
||||
std::wstring b4 = as_wide("\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
|
||||
if (wcharsize == 4)
|
||||
{
|
||||
CHECK(b4.size() == 3 && b4[0] == wchar_cast(0x97624) && b4[1] == L' ' && b4[2] == wchar_cast(0x1003ff));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(b4.size() == 5 && b4[0] == 0xda1d && b4[1] == 0xde24 && b4[2] == L' ' && b4[3] == 0xdbc0 && b4[4] == 0xdfff);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(as_wide_invalid)
|
||||
{
|
||||
// invalid 1-byte input
|
||||
CHECK(as_wide("a\xb0") == L"a");
|
||||
CHECK(as_wide("a\xb0_") == L"a_");
|
||||
|
||||
// invalid 2-byte input
|
||||
CHECK(as_wide("a\xc0") == L"a");
|
||||
CHECK(as_wide("a\xd0") == L"a");
|
||||
CHECK(as_wide("a\xc0_") == L"a_");
|
||||
CHECK(as_wide("a\xd0_") == L"a_");
|
||||
|
||||
// invalid 3-byte input
|
||||
CHECK(as_wide("a\xe2\x80") == L"a");
|
||||
CHECK(as_wide("a\xe2") == L"a");
|
||||
CHECK(as_wide("a\xe2\x80_") == L"a_");
|
||||
CHECK(as_wide("a\xe2_") == L"a_");
|
||||
|
||||
// invalid 4-byte input
|
||||
CHECK(as_wide("a\xf2\x97\x98") == L"a");
|
||||
CHECK(as_wide("a\xf2\x97") == L"a");
|
||||
CHECK(as_wide("a\xf2") == L"a");
|
||||
CHECK(as_wide("a\xf2\x97\x98_") == L"a_");
|
||||
CHECK(as_wide("a\xf2\x97_") == L"a_");
|
||||
CHECK(as_wide("a\xf2_") == L"a_");
|
||||
|
||||
// invalid 5-byte input
|
||||
std::wstring b5 = as_wide("\xf8\nbcd");
|
||||
CHECK(b5 == L"\nbcd");
|
||||
}
|
||||
|
||||
TEST(as_utf8_empty)
|
||||
{
|
||||
CHECK(as_utf8(L"") == "");
|
||||
}
|
||||
|
||||
TEST(as_utf8_valid_basic)
|
||||
{
|
||||
// valid 1-byte, 2-byte and 3-byte outputs
|
||||
#ifdef U_LITERALS
|
||||
|
@ -41,16 +82,56 @@ TEST(as_utf8)
|
|||
#else
|
||||
CHECK(as_utf8(L"?\x0400\x203D") == "?\xd0\x80\xe2\x80\xbd");
|
||||
#endif
|
||||
|
||||
// valid 4-byte output
|
||||
#if 0
|
||||
// requires 4-byte wchar_t :(
|
||||
CHECK(as_utf8(L"\x97624 \x1003ff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(parse_bom_utf8, "\xef\xbb\xbf<node/>")
|
||||
TEST(as_utf8_valid_astral)
|
||||
{
|
||||
CHECK_NODE(doc, "<node />");
|
||||
// valid 4-byte output
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
|
||||
if (wcharsize == 4)
|
||||
{
|
||||
std::wstring s;
|
||||
s.resize(3);
|
||||
s[0] = wchar_cast(0x97624);
|
||||
s[1] = ' ';
|
||||
s[2] = wchar_cast(0x1003ff);
|
||||
|
||||
CHECK(as_utf8(s.c_str()) == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"\uda1d\ude24 \udbc0\udfff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#else
|
||||
CHECK(as_utf8(L"\xda1d\xde24 \xdbc0\xdfff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TEST(as_utf8_invalid)
|
||||
{
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
|
||||
if (wcharsize == 2)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"a\uda1d") == "a");
|
||||
CHECK(as_utf8(L"a\uda1d_") == "a_");
|
||||
#else
|
||||
CHECK(as_utf8(L"a\xda1d") == "a");
|
||||
CHECK(as_utf8(L"a\xda1d_") == "a_");
|
||||
#endif
|
||||
|
||||
// check incorrect leading code
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"a\ude24") == "a");
|
||||
CHECK(as_utf8(L"a\ude24_") == "a_");
|
||||
#else
|
||||
CHECK(as_utf8(L"a\xde24") == "a");
|
||||
CHECK(as_utf8(L"a\xde24_") == "a_");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,95 +1,309 @@
|
|||
#include "common.hpp"
|
||||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
TEST_XML(write_simple, "<node attr='1'><child>text</child></node>")
|
||||
{
|
||||
CHECK_NODE_EX(doc, "<node attr=\"1\">\n<child>text</child>\n</node>\n", "", 0);
|
||||
CHECK_NODE_EX(doc, STR("<node attr=\"1\">\n<child>text</child>\n</node>\n"), STR(""), 0);
|
||||
}
|
||||
|
||||
TEST_XML(write_raw, "<node attr='1'><child>text</child></node>")
|
||||
{
|
||||
CHECK_NODE_EX(doc, "<node attr=\"1\"><child>text</child></node>", "", format_raw);
|
||||
CHECK_NODE_EX(doc, STR("<node attr=\"1\"><child>text</child></node>"), STR(""), format_raw);
|
||||
}
|
||||
|
||||
TEST_XML(write_indent, "<node attr='1'><child><sub>text</sub></child></node>")
|
||||
{
|
||||
CHECK_NODE_EX(doc, "<node attr=\"1\">\n\t<child>\n\t\t<sub>text</sub>\n\t</child>\n</node>\n", "\t", format_indent);
|
||||
CHECK_NODE_EX(doc, STR("<node attr=\"1\">\n\t<child>\n\t\t<sub>text</sub>\n\t</child>\n</node>\n"), STR("\t"), format_indent);
|
||||
}
|
||||
|
||||
TEST_XML(write_pcdata, "<node attr='1'><child><sub/>text</child></node>")
|
||||
{
|
||||
CHECK_NODE_EX(doc, "<node attr=\"1\">\n\t<child>\n\t\t<sub />\n\t\ttext\n\t</child>\n</node>\n", "\t", format_indent);
|
||||
CHECK_NODE_EX(doc, STR("<node attr=\"1\">\n\t<child>\n\t\t<sub />\n\t\ttext\n\t</child>\n</node>\n"), STR("\t"), format_indent);
|
||||
}
|
||||
|
||||
TEST_XML(write_cdata, "<![CDATA[value]]>")
|
||||
{
|
||||
CHECK_NODE(doc, "<![CDATA[value]]>");
|
||||
CHECK_NODE_EX(doc, "<![CDATA[value]]>\n", "", 0);
|
||||
CHECK_NODE(doc, STR("<![CDATA[value]]>"));
|
||||
CHECK_NODE_EX(doc, STR("<![CDATA[value]]>\n"), STR(""), 0);
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(write_comment, "<!--text-->", parse_default | parse_comments)
|
||||
{
|
||||
CHECK_NODE(doc, "<!--text-->");
|
||||
CHECK_NODE_EX(doc, "<!--text-->\n", "", 0);
|
||||
CHECK_NODE(doc, STR("<!--text-->"));
|
||||
CHECK_NODE_EX(doc, STR("<!--text-->\n"), STR(""), 0);
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(write_pi, "<?name value?>", parse_default | parse_pi)
|
||||
{
|
||||
CHECK_NODE(doc, "<?name value?>");
|
||||
CHECK_NODE_EX(doc, "<?name value?>\n", "", 0);
|
||||
CHECK_NODE(doc, STR("<?name value?>"));
|
||||
CHECK_NODE_EX(doc, STR("<?name value?>\n"), STR(""), 0);
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(write_declaration, "<?xml version='2.0'?>", parse_default | parse_declaration)
|
||||
{
|
||||
CHECK_NODE(doc, "<?xml version=\"2.0\"?>");
|
||||
CHECK_NODE_EX(doc, "<?xml version=\"2.0\"?>\n", "", 0);
|
||||
CHECK_NODE(doc, STR("<?xml version=\"2.0\"?>"));
|
||||
CHECK_NODE_EX(doc, STR("<?xml version=\"2.0\"?>\n"), STR(""), 0);
|
||||
}
|
||||
|
||||
TEST_XML(write_escape, "<node attr=''>text</node>")
|
||||
{
|
||||
doc.child("node").attribute("attr") = "<>'\"&\x04\r\n\t";
|
||||
doc.child("node").first_child().set_value("<>'\"&\x04\r\n\t");
|
||||
doc.child(STR("node")).attribute(STR("attr")) = STR("<>'\"&\x04\r\n\t");
|
||||
doc.child(STR("node")).first_child().set_value(STR("<>'\"&\x04\r\n\t"));
|
||||
|
||||
CHECK_NODE(doc, "<node attr=\"<>'"& \t\"><>'\"&\r\n\t</node>");
|
||||
CHECK_NODE(doc, STR("<node attr=\"<>'"& \t\"><>'\"&\r\n\t</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(write_escape_unicode, "<node attr='㰀'/>")
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef U_LITERALS
|
||||
CHECK_NODE(doc, STR("<node attr=\"\u3c00\" />"));
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\x3c00\" />"));
|
||||
#endif
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\xe3\xb0\x80\" />"));
|
||||
#endif
|
||||
}
|
||||
|
||||
struct test_writer: xml_writer
|
||||
{
|
||||
std::string contents;
|
||||
std::basic_string<pugi::char_t> contents;
|
||||
|
||||
virtual void write(const void* data, size_t size)
|
||||
{
|
||||
contents += std::string(static_cast<const char*>(data), static_cast<const char*>(data) + size);
|
||||
CHECK(size % sizeof(pugi::char_t) == 0);
|
||||
contents += std::basic_string<pugi::char_t>(static_cast<const pugi::char_t*>(data), static_cast<const pugi::char_t*>(data) + size / sizeof(pugi::char_t));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_XML(write_print_writer, "<node/>")
|
||||
{
|
||||
test_writer writer;
|
||||
doc.print(writer);
|
||||
doc.print(writer, STR(""), format_default, get_native_encoding());
|
||||
|
||||
CHECK(writer.contents == "<node />\n");
|
||||
CHECK(writer.contents == STR("<node />\n"));
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
TEST_XML(write_print_stream, "<node/>")
|
||||
{
|
||||
std::ostringstream oss;
|
||||
doc.print(oss);
|
||||
doc.print(oss, STR(""), format_default, encoding_utf8);
|
||||
|
||||
CHECK(oss.str() == "<node />\n");
|
||||
}
|
||||
|
||||
TEST_XML(write_print_stream_encode, "<n/>")
|
||||
{
|
||||
std::ostringstream oss;
|
||||
doc.print(oss, STR(""), format_default, encoding_utf16_be);
|
||||
|
||||
CHECK(oss.str() == std::string("\x00<\x00n\x00 \x00/\x00>\x00\n", 12));
|
||||
}
|
||||
|
||||
TEST_XML(write_print_stream_wide, "<node/>")
|
||||
{
|
||||
std::basic_ostringstream<wchar_t> oss;
|
||||
doc.print(oss, STR(""), format_default, encoding_utf8);
|
||||
|
||||
CHECK(oss.str() == L"<node />\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(write_huge_chunk, "<node/>")
|
||||
{
|
||||
std::string name(10000, 'n');
|
||||
doc.child("node").set_name(name.c_str());
|
||||
std::basic_string<pugi::char_t> name(10000, STR('n'));
|
||||
doc.child(STR("node")).set_name(name.c_str());
|
||||
|
||||
test_writer writer;
|
||||
doc.print(writer);
|
||||
doc.print(writer, STR(""), format_default, get_native_encoding());
|
||||
|
||||
CHECK(writer.contents == "<" + name + " />\n");
|
||||
CHECK(writer.contents == STR("<") + name + STR(" />\n"));
|
||||
}
|
||||
|
||||
TEST(write_encodings)
|
||||
{
|
||||
static char s_utf8[] = "<\x54\xC2\xA2\xE2\x82\xAC\xF0\xA4\xAD\xA2/>";
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(s_utf8, sizeof(s_utf8), parse_default, encoding_utf8));
|
||||
|
||||
CHECK(write_narrow(doc, format_default, encoding_utf8) == "<\x54\xC2\xA2\xE2\x82\xAC\xF0\xA4\xAD\xA2 />\n");
|
||||
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf32_le, "<\x00\x00\x00\x54\x00\x00\x00\xA2\x00\x00\x00\xAC\x20\x00\x00\x62\x4B\x02\x00 \x00\x00\x00/\x00\x00\x00>\x00\x00\x00\n\x00\x00\x00", 36));
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf32_be, "\x00\x00\x00<\x00\x00\x00\x54\x00\x00\x00\xA2\x00\x00\x20\xAC\x00\x02\x4B\x62\x00\x00\x00 \x00\x00\x00/\x00\x00\x00>\x00\x00\x00\n", 36));
|
||||
CHECK(write_narrow(doc, format_default, encoding_utf32) == write_narrow(doc, format_default, is_little_endian() ? encoding_utf32_le : encoding_utf32_be));
|
||||
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf16_le, "<\x00\x54\x00\xA2\x00\xAC\x20\x52\xd8\x62\xdf \x00/\x00>\x00\n\x00", 20));
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf16_be, "\x00<\x00\x54\x00\xA2\x20\xAC\xd8\x52\xdf\x62\x00 \x00/\x00>\x00\n", 20));
|
||||
CHECK(write_narrow(doc, format_default, encoding_utf16) == write_narrow(doc, format_default, is_little_endian() ? encoding_utf16_le : encoding_utf16_be));
|
||||
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
std::wstring v = write_wide(doc, format_default, encoding_wchar);
|
||||
|
||||
if (wcharsize == 4)
|
||||
{
|
||||
CHECK(v.size() == 9 && v[0] == '<' && v[1] == 0x54 && v[2] == 0xA2 && v[3] == 0x20AC && v[4] == wchar_cast(0x24B62) && v[5] == ' ' && v[6] == '/' && v[7] == '>' && v[8] == '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(v.size() == 10 && v[0] == '<' && v[1] == 0x54 && v[2] == 0xA2 && v[3] == 0x20AC && v[4] == 0xd852 && v[5] == 0xdf62 && v[6] == ' ' && v[7] == '/' && v[8] == '>' && v[9] == '\n');
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
TEST(write_encoding_huge)
|
||||
{
|
||||
const unsigned int N = 16000;
|
||||
|
||||
// make a large utf16 name consisting of 6-byte char pairs (6 does not divide internal buffer size, so will need split correction)
|
||||
std::string s_utf16 = std::string("\x00<", 2);
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf16 += "\x20\xAC\xd8\x52\xdf\x62";
|
||||
|
||||
s_utf16 += std::string("\x00/\x00>", 4);
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(&s_utf16[0], s_utf16.length(), parse_default, encoding_utf16_be));
|
||||
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int j = 0; j < N; ++j) s_utf8 += "\xE2\x82\xAC\xF0\xA4\xAD\xA2";
|
||||
|
||||
s_utf8 += " />\n";
|
||||
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf8, s_utf8.c_str(), s_utf8.length()));
|
||||
}
|
||||
#else
|
||||
TEST(write_encoding_huge)
|
||||
{
|
||||
const unsigned int N = 16000;
|
||||
|
||||
// make a large utf8 name consisting of 3-byte chars (3 does not divide internal buffer size, so will need split correction)
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf8 += "\xE2\x82\xAC";
|
||||
|
||||
s_utf8 += "/>";
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(&s_utf8[0], s_utf8.length(), parse_default, encoding_utf8));
|
||||
|
||||
std::string s_utf16 = std::string("\x00<", 2);
|
||||
|
||||
for (unsigned int j = 0; j < N; ++j) s_utf16 += "\x20\xAC";
|
||||
|
||||
s_utf16 += std::string("\x00 \x00/\x00>\x00\n", 8);
|
||||
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf16_be, s_utf16.c_str(), s_utf16.length()));
|
||||
}
|
||||
|
||||
TEST(write_encoding_huge_invalid)
|
||||
{
|
||||
const unsigned int N = 16000;
|
||||
|
||||
// make a large utf8 name consisting of non-leading chars
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf8 += "\x82";
|
||||
|
||||
s_utf8 += "/>";
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(&s_utf8[0], s_utf8.length(), parse_default, encoding_utf8));
|
||||
|
||||
std::string s_utf16 = std::string("\x00<\x00 \x00/\x00>\x00\n", 10);
|
||||
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_utf16_be, s_utf16.c_str(), s_utf16.length()));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(write_unicode_escape)
|
||||
{
|
||||
char s_utf8[] = "<\xE2\x82\xAC \xC2\xA2='\"\xF0\xA4\xAD\xA2
\"'>&\x14\xF0\xA4\xAD\xA2<</\xE2\x82\xAC>";
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(s_utf8, sizeof(s_utf8), parse_default, encoding_utf8));
|
||||
|
||||
CHECK(write_narrow(doc, format_default, encoding_utf8) == "<\xE2\x82\xAC \xC2\xA2=\""\xF0\xA4\xAD\xA2 "\">&\xF0\xA4\xAD\xA2<</\xE2\x82\xAC>\n");
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
static bool test_write_unicode_invalid(const wchar_t* name, const char* expected)
|
||||
{
|
||||
xml_document doc;
|
||||
doc.append_child(node_pcdata).set_value(name);
|
||||
|
||||
return write_narrow(doc, format_raw, encoding_utf8) == expected;
|
||||
}
|
||||
|
||||
TEST(write_unicode_invalid_utf16)
|
||||
{
|
||||
size_t wcharsize = sizeof(wchar_t);
|
||||
|
||||
if (wcharsize == 2)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
#ifdef U_LITERALS
|
||||
CHECK(test_write_unicode_invalid(L"a\uda1d", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\uda1d_", "a_"));
|
||||
#else
|
||||
CHECK(test_write_unicode_invalid(L"a\xda1d", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\xda1d_", "a_"));
|
||||
#endif
|
||||
|
||||
// check incorrect leading code
|
||||
#ifdef U_LITERALS
|
||||
CHECK(test_write_unicode_invalid(L"a\ude24", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\ude24_", "a_"));
|
||||
#else
|
||||
CHECK(test_write_unicode_invalid(L"a\xde24", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\xde24_", "a_"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
static bool test_write_unicode_invalid(const char* name, const wchar_t* expected)
|
||||
{
|
||||
xml_document doc;
|
||||
doc.append_child(node_pcdata).set_value(name);
|
||||
|
||||
return write_wide(doc, format_raw, encoding_wchar) == expected;
|
||||
}
|
||||
|
||||
TEST(write_unicode_invalid_utf8)
|
||||
{
|
||||
// invalid 1-byte input
|
||||
CHECK(test_write_unicode_invalid("a\xb0", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xb0_", L"a_"));
|
||||
|
||||
// invalid 2-byte input
|
||||
CHECK(test_write_unicode_invalid("a\xc0", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xd0", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xc0_", L"a_"));
|
||||
CHECK(test_write_unicode_invalid("a\xd0_", L"a_"));
|
||||
|
||||
// invalid 3-byte input
|
||||
CHECK(test_write_unicode_invalid("a\xe2\x80", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xe2", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xe2\x80_", L"a_"));
|
||||
CHECK(test_write_unicode_invalid("a\xe2_", L"a_"));
|
||||
|
||||
// invalid 4-byte input
|
||||
CHECK(test_write_unicode_invalid("a\xf2\x97\x98", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xf2\x97", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xf2", L"a"));
|
||||
CHECK(test_write_unicode_invalid("a\xf2\x97\x98_", L"a_"));
|
||||
CHECK(test_write_unicode_invalid("a\xf2\x97_", L"a_"));
|
||||
CHECK(test_write_unicode_invalid("a\xf2_", L"a_"));
|
||||
|
||||
// invalid 5-byte input
|
||||
CHECK(test_write_unicode_invalid("a\xf8_", L"a_"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,46 +2,52 @@
|
|||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST_XML(xpath_document_order, "<node><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2></node>")
|
||||
{
|
||||
CHECK(xml_node().document_order() == 0);
|
||||
CHECK(doc.child("node").document_order() == 0);
|
||||
CHECK(doc.child(STR("node")).document_order() == 0);
|
||||
CHECK(doc.document_order() == 0);
|
||||
|
||||
doc.precompute_document_order();
|
||||
|
||||
CHECK(doc.document_order() == 1);
|
||||
CHECK(doc.child("node").document_order() == 2);
|
||||
CHECK(doc.child("node").child("child1").document_order() == 3);
|
||||
CHECK(doc.child("node").child("child1").attribute("attr1").document_order() == 4);
|
||||
CHECK(doc.child("node").child("child1").attribute("attr2").document_order() == 5);
|
||||
CHECK(doc.child("node").child("child2").document_order() == 6);
|
||||
CHECK(doc.child("node").child("child2").attribute("attr1").document_order() == 7);
|
||||
CHECK(doc.child("node").child("child2").first_child().document_order() == 8);
|
||||
CHECK(doc.child(STR("node")).document_order() == 2);
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).document_order() == 3);
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).attribute(STR("attr1")).document_order() == 4);
|
||||
CHECK(doc.child(STR("node")).child(STR("child1")).attribute(STR("attr2")).document_order() == 5);
|
||||
CHECK(doc.child(STR("node")).child(STR("child2")).document_order() == 6);
|
||||
CHECK(doc.child(STR("node")).child(STR("child2")).attribute(STR("attr1")).document_order() == 7);
|
||||
CHECK(doc.child(STR("node")).child(STR("child2")).first_child().document_order() == 8);
|
||||
}
|
||||
|
||||
TEST(xpath_allocator_many_pages)
|
||||
{
|
||||
std::string query = "0";
|
||||
pugi::string_t query = STR("0");
|
||||
|
||||
for (int i = 0; i < 128; ++i) query += "+string-length('abcdefgh')";
|
||||
for (int i = 0; i < 128; ++i) query += STR("+string-length('abcdefgh')");
|
||||
|
||||
CHECK_XPATH_NUMBER(xml_node(), query.c_str(), 1024);
|
||||
}
|
||||
|
||||
TEST(xpath_allocator_large_page)
|
||||
{
|
||||
std::string query;
|
||||
pugi::string_t query;
|
||||
|
||||
for (int i = 0; i < 1024; ++i) query += "abcdefgh";
|
||||
for (int i = 0; i < 1024; ++i) query += STR("abcdefgh");
|
||||
|
||||
CHECK_XPATH_NUMBER(xml_node(), ("string-length('" + query + "')").c_str(), 8192);
|
||||
CHECK_XPATH_NUMBER(xml_node(), (STR("string-length('") + query + STR("')")).c_str(), 8192);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_sort_complex, "<node><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2></node>")
|
||||
{
|
||||
// just some random union order, it should not matter probably?
|
||||
xpath_node_set ns = doc.child("node").select_nodes("child1 | child2 | child1/@* | . | child2/@* | child2/text()");
|
||||
xpath_node_set ns = doc.child(STR("node")).select_nodes(STR("child1 | child2 | child1/@* | . | child2/@* | child2/text()"));
|
||||
|
||||
ns.sort(false);
|
||||
xpath_node_set sorted = ns;
|
||||
|
@ -57,7 +63,7 @@ TEST_XML(xpath_sort_complex, "<node><child1 attr1='value1' attr2='value2'/><chil
|
|||
|
||||
TEST_XML(xpath_sort_children, "<node><child><subchild id='1'/></child><child><subchild id='2'/></child></node>")
|
||||
{
|
||||
xpath_node_set ns = doc.child("node").select_nodes("child/subchild[@id=1] | child/subchild[@id=2]");
|
||||
xpath_node_set ns = doc.child(STR("node")).select_nodes(STR("child/subchild[@id=1] | child/subchild[@id=2]"));
|
||||
|
||||
ns.sort(false);
|
||||
xpath_node_set sorted = ns;
|
||||
|
@ -73,15 +79,15 @@ TEST_XML(xpath_sort_children, "<node><child><subchild id='1'/></child><child><su
|
|||
|
||||
TEST_XML(xpath_sort_attributes, "<node/>")
|
||||
{
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// we need to insert attributes manually since unsorted node sets are (always?) sorted via pointers because of remove_duplicates,
|
||||
// so we need to have different document and pointer order to cover all comparator cases
|
||||
n.append_attribute("attr2");
|
||||
n.append_attribute("attr3");
|
||||
n.insert_attribute_before("attr1", n.attribute("attr2"));
|
||||
n.append_attribute(STR("attr2"));
|
||||
n.append_attribute(STR("attr3"));
|
||||
n.insert_attribute_before(STR("attr1"), n.attribute(STR("attr2")));
|
||||
|
||||
xpath_node_set ns = n.select_nodes("@*");
|
||||
xpath_node_set ns = n.select_nodes(STR("@*"));
|
||||
|
||||
ns.sort(true);
|
||||
xpath_node_set reverse_sorted = ns;
|
||||
|
@ -95,4 +101,54 @@ TEST_XML(xpath_sort_attributes, "<node/>")
|
|||
xpath_node_set_tester(reverse_sorted, "reverse sorted order failed") % 5 % 4 % 3;
|
||||
}
|
||||
|
||||
TEST(xpath_long_numbers_parse)
|
||||
{
|
||||
const pugi::char_t* str_flt_max = STR("340282346638528860000000000000000000000");
|
||||
const pugi::char_t* str_flt_max_dec = STR("340282346638528860000000000000000000000.000000");
|
||||
|
||||
const pugi::char_t* str_dbl_max = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
const pugi::char_t* str_dbl_max_dec = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000");
|
||||
|
||||
xml_node c;
|
||||
|
||||
// check parsing
|
||||
CHECK_XPATH_NUMBER(c, str_flt_max, FLT_MAX);
|
||||
CHECK_XPATH_NUMBER(c, str_flt_max_dec, FLT_MAX);
|
||||
CHECK_XPATH_NUMBER(c, str_dbl_max, DBL_MAX);
|
||||
CHECK_XPATH_NUMBER(c, str_dbl_max_dec, DBL_MAX);
|
||||
}
|
||||
|
||||
static bool test_xpath_string_prefix(const pugi::xml_node& node, const pugi::char_t* query, const pugi::char_t* expected, size_t match_length)
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
size_t expected_length = wcslen(expected);
|
||||
#else
|
||||
size_t expected_length = strlen(expected);
|
||||
#endif
|
||||
|
||||
pugi::xpath_query q(query);
|
||||
pugi::string_t value = q.evaluate_string(node);
|
||||
|
||||
return value.length() == expected_length && value.compare(0, match_length, expected, match_length) == 0;
|
||||
}
|
||||
|
||||
TEST(xpath_long_numbers_stringize)
|
||||
{
|
||||
const pugi::char_t* str_flt_max = STR("340282346638528860000000000000000000000");
|
||||
const pugi::char_t* str_flt_max_dec = STR("340282346638528860000000000000000000000.000000");
|
||||
|
||||
const pugi::char_t* str_dbl_max = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
const pugi::char_t* str_dbl_max_dec = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000");
|
||||
|
||||
xml_node c;
|
||||
|
||||
CHECK(test_xpath_string_prefix(c, str_flt_max, str_flt_max, 16));
|
||||
CHECK(test_xpath_string_prefix(c, str_flt_max_dec, str_flt_max, 16));
|
||||
|
||||
#ifndef __BORLANDC__ // printf with %f format still results in 1.xxxe+308 form
|
||||
CHECK(test_xpath_string_prefix(c, str_dbl_max, str_dbl_max, 16));
|
||||
CHECK(test_xpath_string_prefix(c, str_dbl_max_dec, str_dbl_max, 16));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,13 +4,15 @@
|
|||
|
||||
#include "helpers.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST_XML(xpath_api_select_nodes, "<node><head/><foo/><foo/><tail/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xpath_node_set ns1 = doc.select_nodes("node/foo");
|
||||
xpath_node_set ns1 = doc.select_nodes(STR("node/foo"));
|
||||
|
||||
xpath_query q("node/foo");
|
||||
xpath_query q(STR("node/foo"));
|
||||
xpath_node_set ns2 = doc.select_nodes(q);
|
||||
|
||||
CHECK(ns1.size() == 2 && ns1[0].node().document_order() == 4 && ns1[1].node().document_order() == 5);
|
||||
|
@ -21,20 +23,20 @@ TEST_XML(xpath_api_select_single_node, "<node><head/><foo/><foo/><tail/></node>"
|
|||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xpath_node n1 = doc.select_single_node("node/foo");
|
||||
xpath_node n1 = doc.select_single_node(STR("node/foo"));
|
||||
|
||||
xpath_query q("node/foo");
|
||||
xpath_query q(STR("node/foo"));
|
||||
xpath_node n2 = doc.select_single_node(q);
|
||||
|
||||
CHECK(n1.node().document_order() == 4);
|
||||
CHECK(n2.node().document_order() == 4);
|
||||
|
||||
xpath_node n3 = doc.select_single_node("node/bar");
|
||||
xpath_node n3 = doc.select_single_node(STR("node/bar"));
|
||||
|
||||
CHECK(!n3);
|
||||
|
||||
xpath_node n4 = doc.select_single_node("node/head/following-sibling::foo");
|
||||
xpath_node n5 = doc.select_single_node("node/tail/preceding-sibling::foo");
|
||||
xpath_node n4 = doc.select_single_node(STR("node/head/following-sibling::foo"));
|
||||
xpath_node n5 = doc.select_single_node(STR("node/tail/preceding-sibling::foo"));
|
||||
|
||||
CHECK(n4.node().document_order() == 4);
|
||||
CHECK(n5.node().document_order() == 4);
|
||||
|
@ -44,7 +46,7 @@ TEST(xpath_api_exception_what)
|
|||
{
|
||||
try
|
||||
{
|
||||
xpath_query q("");
|
||||
xpath_query q(STR(""));
|
||||
}
|
||||
catch (const xpath_exception& e)
|
||||
{
|
||||
|
@ -54,32 +56,32 @@ TEST(xpath_api_exception_what)
|
|||
|
||||
TEST_XML(xpath_api_node_bool_ops, "<node attr='value'/>")
|
||||
{
|
||||
generic_bool_ops_test(doc.select_single_node("node"));
|
||||
generic_bool_ops_test(doc.select_single_node("node/@attr"));
|
||||
generic_bool_ops_test(doc.select_single_node(STR("node")));
|
||||
generic_bool_ops_test(doc.select_single_node(STR("node/@attr")));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_api_node_eq_ops, "<node attr='value'/>")
|
||||
{
|
||||
generic_eq_ops_test(doc.select_single_node("node"), doc.select_single_node("node/@attr"));
|
||||
generic_eq_ops_test(doc.select_single_node(STR("node")), doc.select_single_node(STR("node/@attr")));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_api_node_accessors, "<node attr='value'/>")
|
||||
{
|
||||
xpath_node null;
|
||||
xpath_node node = doc.select_single_node("node");
|
||||
xpath_node attr = doc.select_single_node("node/@attr");
|
||||
xpath_node node = doc.select_single_node(STR("node"));
|
||||
xpath_node attr = doc.select_single_node(STR("node/@attr"));
|
||||
|
||||
CHECK(!null.node());
|
||||
CHECK(!null.attribute());
|
||||
CHECK(!null.parent());
|
||||
|
||||
CHECK(node.node() == doc.child("node"));
|
||||
CHECK(node.node() == doc.child(STR("node")));
|
||||
CHECK(!node.attribute());
|
||||
CHECK(node.parent() == doc);
|
||||
|
||||
CHECK(!attr.node());
|
||||
CHECK(attr.attribute() == doc.child("node").attribute("attr"));
|
||||
CHECK(attr.parent() == doc.child("node"));
|
||||
CHECK(attr.attribute() == doc.child(STR("node")).attribute(STR("attr")));
|
||||
CHECK(attr.parent() == doc.child(STR("node")));
|
||||
}
|
||||
|
||||
inline void xpath_api_node_accessors_helper(const xpath_node_set& set)
|
||||
|
@ -87,8 +89,8 @@ inline void xpath_api_node_accessors_helper(const xpath_node_set& set)
|
|||
CHECK(set.size() == 2);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted);
|
||||
CHECK(!set.empty());
|
||||
CHECK_STRING(set[0].node().name(), "foo");
|
||||
CHECK_STRING(set[1].node().name(), "foo");
|
||||
CHECK_STRING(set[0].node().name(), STR("foo"));
|
||||
CHECK_STRING(set[1].node().name(), STR("foo"));
|
||||
CHECK(!set[2]);
|
||||
CHECK(set.first() == set[0]);
|
||||
CHECK(set.begin() + 2 == set.end());
|
||||
|
@ -105,7 +107,7 @@ TEST_XML(xpath_api_nodeset_accessors, "<node><foo/><foo/></node>")
|
|||
CHECK(!null.first());
|
||||
CHECK(null.begin() == null.end());
|
||||
|
||||
xpath_node_set set = doc.select_nodes("node/foo");
|
||||
xpath_node_set set = doc.select_nodes(STR("node/foo"));
|
||||
xpath_api_node_accessors_helper(set);
|
||||
|
||||
xpath_node_set copy = set;
|
||||
|
@ -120,21 +122,21 @@ TEST_XML(xpath_api_nodeset_accessors, "<node><foo/><foo/></node>")
|
|||
|
||||
TEST_XML(xpath_api_evaluate, "<node attr='3'/>")
|
||||
{
|
||||
xpath_query q("node/@attr");
|
||||
xpath_query q(STR("node/@attr"));
|
||||
|
||||
CHECK(q.evaluate_boolean(doc));
|
||||
CHECK(q.evaluate_number(doc) == 3);
|
||||
CHECK(q.evaluate_string(doc) == "3");
|
||||
CHECK(q.evaluate_string(doc) == STR("3"));
|
||||
|
||||
xpath_node_set ns = q.evaluate_node_set(doc);
|
||||
CHECK(ns.size() == 1 && ns[0].attribute() == doc.child("node").attribute("attr"));
|
||||
CHECK(ns.size() == 1 && ns[0].attribute() == doc.child(STR("node")).attribute(STR("attr")));
|
||||
}
|
||||
|
||||
TEST(xpath_api_evaluate_node_set)
|
||||
{
|
||||
try
|
||||
{
|
||||
xpath_query q("1");
|
||||
xpath_query q(STR("1"));
|
||||
|
||||
q.evaluate_node_set(xml_node());
|
||||
}
|
||||
|
@ -145,10 +147,10 @@ TEST(xpath_api_evaluate_node_set)
|
|||
|
||||
TEST(xpath_api_return_type)
|
||||
{
|
||||
CHECK(xpath_query("node").return_type() == xpath_type_node_set);
|
||||
CHECK(xpath_query("1").return_type() == xpath_type_number);
|
||||
CHECK(xpath_query("'s'").return_type() == xpath_type_string);
|
||||
CHECK(xpath_query("true()").return_type() == xpath_type_boolean);
|
||||
CHECK(xpath_query(STR("node")).return_type() == xpath_type_node_set);
|
||||
CHECK(xpath_query(STR("1")).return_type() == xpath_type_number);
|
||||
CHECK(xpath_query(STR("'s'")).return_type() == xpath_type_string);
|
||||
CHECK(xpath_query(STR("true()")).return_type() == xpath_type_boolean);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,65 +17,65 @@
|
|||
TEST_XML(xpath_operators_arithmetic, "<node><foo-bar>10</foo-bar><foo>2</foo><bar>3</bar></node>")
|
||||
{
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// incorrect unary operator
|
||||
CHECK_XPATH_FAIL("-");
|
||||
CHECK_XPATH_FAIL(STR("-"));
|
||||
|
||||
// correct unary operator
|
||||
CHECK_XPATH_NUMBER(c, "-1", -1);
|
||||
CHECK_XPATH_NUMBER(c, "--1", 1);
|
||||
CHECK_XPATH_NUMBER(c, "---1", -1);
|
||||
CHECK_XPATH_NUMBER(c, STR("-1"), -1);
|
||||
CHECK_XPATH_NUMBER(c, STR("--1"), 1);
|
||||
CHECK_XPATH_NUMBER(c, STR("---1"), -1);
|
||||
|
||||
// incorrect binary operators
|
||||
CHECK_XPATH_FAIL("5+");
|
||||
CHECK_XPATH_FAIL("5-");
|
||||
CHECK_XPATH_FAIL("5*");
|
||||
CHECK_XPATH_FAIL("+5");
|
||||
CHECK_XPATH_FAIL("*5");
|
||||
CHECK_XPATH_FAIL("1div2");
|
||||
CHECK_XPATH_FAIL("1mod");
|
||||
CHECK_XPATH_FAIL("1div");
|
||||
CHECK_XPATH_FAIL(STR("5+"));
|
||||
CHECK_XPATH_FAIL(STR("5-"));
|
||||
CHECK_XPATH_FAIL(STR("5*"));
|
||||
CHECK_XPATH_FAIL(STR("+5"));
|
||||
CHECK_XPATH_FAIL(STR("*5"));
|
||||
CHECK_XPATH_FAIL(STR("1div2"));
|
||||
CHECK_XPATH_FAIL(STR("1mod"));
|
||||
CHECK_XPATH_FAIL(STR("1div"));
|
||||
|
||||
// correct trivial binary operators
|
||||
CHECK_XPATH_NUMBER(c, "1 + 2", 3);
|
||||
CHECK_XPATH_NUMBER(c, "1+2", 3);
|
||||
CHECK_XPATH_NUMBER(c, "1 * 2", 2);
|
||||
CHECK_XPATH_NUMBER(c, "1*2", 2);
|
||||
CHECK_XPATH_NUMBER(c, "1 div 2", 0.5);
|
||||
CHECK_XPATH_NUMBER(c, STR("1 + 2"), 3);
|
||||
CHECK_XPATH_NUMBER(c, STR("1+2"), 3);
|
||||
CHECK_XPATH_NUMBER(c, STR("1 * 2"), 2);
|
||||
CHECK_XPATH_NUMBER(c, STR("1*2"), 2);
|
||||
CHECK_XPATH_NUMBER(c, STR("1 div 2"), 0.5);
|
||||
|
||||
// operator precedence
|
||||
CHECK_XPATH_NUMBER(c, "2 + 2 * 2 div 1 mod 3", 3);
|
||||
CHECK_XPATH_NUMBER(c, "2 + 2 * 2 div (1 mod 3)", 6);
|
||||
CHECK_XPATH_NUMBER(c, "(2 + 2) * 2 div (1 mod 3)", 8);
|
||||
CHECK_XPATH_NUMBER(c, "(2 + 2) * (2 div 1) mod 3", 2);
|
||||
CHECK_XPATH_NUMBER(c, "2 - -2", 4);
|
||||
CHECK_XPATH_NUMBER(c, "2--2", 4);
|
||||
CHECK_XPATH_NUMBER(c, "1-2-3", -4);
|
||||
CHECK_XPATH_NUMBER(c, STR("2 + 2 * 2 div 1 mod 3"), 3);
|
||||
CHECK_XPATH_NUMBER(c, STR("2 + 2 * 2 div (1 mod 3)"), 6);
|
||||
CHECK_XPATH_NUMBER(c, STR("(2 + 2) * 2 div (1 mod 3)"), 8);
|
||||
CHECK_XPATH_NUMBER(c, STR("(2 + 2) * (2 div 1) mod 3"), 2);
|
||||
CHECK_XPATH_NUMBER(c, STR("2 - -2"), 4);
|
||||
CHECK_XPATH_NUMBER(c, STR("2--2"), 4);
|
||||
CHECK_XPATH_NUMBER(c, STR("1-2-3"), -4);
|
||||
|
||||
// infinity/nan
|
||||
CHECK_XPATH_STRING(c, "1 div 0", "Infinity");
|
||||
CHECK_XPATH_STRING(c, "-1 div 0", "-Infinity");
|
||||
CHECK_XPATH_STRING(c, "-1 div 0 + 1 div 0", "NaN");
|
||||
CHECK_XPATH_STRING(c, "0 div 0", "NaN");
|
||||
CHECK_XPATH_STRING(c, "1 div 0 + 1 div 0", "Infinity");
|
||||
CHECK_XPATH_STRING(c, "-1 div 0 + -1 div 0", "-Infinity");
|
||||
CHECK_XPATH_STRING(c, "1 div 0 + 100", "Infinity");
|
||||
CHECK_XPATH_STRING(c, "-1 div 0 + 100", "-Infinity");
|
||||
CHECK_XPATH_STRING(c, "0 div 0 + 100", "NaN");
|
||||
CHECK_XPATH_STRING(c, STR("1 div 0"), STR("Infinity"));
|
||||
CHECK_XPATH_STRING(c, STR("-1 div 0"), STR("-Infinity"));
|
||||
CHECK_XPATH_STRING(c, STR("-1 div 0 + 1 div 0"), STR("NaN"));
|
||||
CHECK_XPATH_STRING(c, STR("0 div 0"), STR("NaN"));
|
||||
CHECK_XPATH_STRING(c, STR("1 div 0 + 1 div 0"), STR("Infinity"));
|
||||
CHECK_XPATH_STRING(c, STR("-1 div 0 + -1 div 0"), STR("-Infinity"));
|
||||
CHECK_XPATH_STRING(c, STR("1 div 0 + 100"), STR("Infinity"));
|
||||
CHECK_XPATH_STRING(c, STR("-1 div 0 + 100"), STR("-Infinity"));
|
||||
CHECK_XPATH_STRING(c, STR("0 div 0 + 100"), STR("NaN"));
|
||||
|
||||
// mod, from W3C standard
|
||||
CHECK_XPATH_NUMBER(c, "5 mod 2", 1);
|
||||
CHECK_XPATH_NUMBER(c, "5 mod -2", 1);
|
||||
CHECK_XPATH_NUMBER(c, "-5 mod 2", -1);
|
||||
CHECK_XPATH_NUMBER(c, "-5 mod -2", -1);
|
||||
CHECK_XPATH_NUMBER(c, STR("5 mod 2"), 1);
|
||||
CHECK_XPATH_NUMBER(c, STR("5 mod -2"), 1);
|
||||
CHECK_XPATH_NUMBER(c, STR("-5 mod 2"), -1);
|
||||
CHECK_XPATH_NUMBER(c, STR("-5 mod -2"), -1);
|
||||
|
||||
// correct subtraction parsing, from W3C standard
|
||||
CHECK_XPATH_NUMBER(n, "foo-bar", 10);
|
||||
CHECK_XPATH_NUMBER(n, "foo -bar", -1);
|
||||
CHECK_XPATH_NUMBER(n, "foo - bar", -1);
|
||||
CHECK_XPATH_NUMBER(n, "-foo-bar", -10);
|
||||
CHECK_XPATH_NUMBER(n, "-foo -bar", -5);
|
||||
CHECK_XPATH_NUMBER(n, STR("foo-bar"), 10);
|
||||
CHECK_XPATH_NUMBER(n, STR("foo -bar"), -1);
|
||||
CHECK_XPATH_NUMBER(n, STR("foo - bar"), -1);
|
||||
CHECK_XPATH_NUMBER(n, STR("-foo-bar"), -10);
|
||||
CHECK_XPATH_NUMBER(n, STR("-foo -bar"), -5);
|
||||
}
|
||||
|
||||
TEST(xpath_operators_logical)
|
||||
|
@ -83,21 +83,21 @@ TEST(xpath_operators_logical)
|
|||
xml_node c;
|
||||
|
||||
// boolean arithmetic
|
||||
CHECK_XPATH_BOOLEAN(c, "true() or true()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "true() or false()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() or false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() or true()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() or true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() or false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() or false()"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() or true()"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(c, "true() and true()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "true() and false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() and false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() and true()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() and true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() and false()"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() and false()"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() and true()"), false);
|
||||
|
||||
// boolean conversion
|
||||
CHECK_XPATH_BOOLEAN(c, "1 or ''", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 and ''", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 or ''", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 or 'a'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 or ''"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 and ''"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 or ''"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 or 'a'"), true);
|
||||
}
|
||||
|
||||
TEST(xpath_operators_equality_primitive_boolean)
|
||||
|
@ -105,25 +105,25 @@ TEST(xpath_operators_equality_primitive_boolean)
|
|||
xml_node c;
|
||||
|
||||
// boolean vs boolan
|
||||
CHECK_XPATH_BOOLEAN(c, "true() = true()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() = false()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "true() != false()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() != false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() = true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() = false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() != false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() != false()"), false);
|
||||
|
||||
// upcast to boolean
|
||||
CHECK_XPATH_BOOLEAN(c, "true() = 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "true() != 2", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() = 2", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() != 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() = 0", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "false() != 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() = 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("true() != 2"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() = 2"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() != 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() = 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("false() != 0"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(c, "2 = true()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 != true()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 = false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 != false()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 = false()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 != false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 = true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 != true()"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 = false()"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 != false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 = false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 != false()"), false);
|
||||
}
|
||||
|
||||
TEST(xpath_operators_equality_primitive_number)
|
||||
|
@ -131,26 +131,26 @@ TEST(xpath_operators_equality_primitive_number)
|
|||
xml_node c;
|
||||
|
||||
// number vs number
|
||||
CHECK_XPATH_BOOLEAN(c, "1 = 1", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "0.5 = 0.5", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 != 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 = -1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 = 1"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0.5 = 0.5"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 != 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 = -1"), false);
|
||||
|
||||
// infinity/nan
|
||||
CHECK_XPATH_BOOLEAN(c, "1 div 0 = 2 div 0", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "-1 div 0 != 2 div 0", true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 div 0 = 2 div 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("-1 div 0 != 2 div 0"), true);
|
||||
|
||||
#ifndef MSVC6_NAN_BUG
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 = 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 != 1", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 = 0 div 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 = 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 != 1"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 = 0 div 0"), false);
|
||||
#endif
|
||||
|
||||
// upcast to number
|
||||
CHECK_XPATH_BOOLEAN(c, "2 = '2'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 != '2'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "'1' != 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "'1' = 2", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 = '2'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 != '2'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'1' != 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'1' = 2"), false);
|
||||
}
|
||||
|
||||
TEST(xpath_operators_equality_primitive_string)
|
||||
|
@ -158,104 +158,104 @@ TEST(xpath_operators_equality_primitive_string)
|
|||
xml_node c;
|
||||
|
||||
// string vs string
|
||||
CHECK_XPATH_BOOLEAN(c, "'a' = 'a'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "'a' = 'b'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "'ab' != 'a'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "'' != 'a'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "'a' != ''", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "'' != ''", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'a' = 'a'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'a' = 'b'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'ab' != 'a'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'' != 'a'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'a' != ''"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'' != ''"), false);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_operators_equality_node_set_node_set, "<node><c1><v>a</v><v>b</v></c1><c2><v>a</v><v>c</v></c2><c3><v>b</v></c3><c4><v>d</v></c4><c5><v>a</v><v>b</v></c5><c6><v>b</v></c6></node>")
|
||||
{
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// node set vs node set
|
||||
CHECK_XPATH_BOOLEAN(c, "x = x", false); // empty node set compares as false with any other object via any comparison operator, as per XPath spec
|
||||
CHECK_XPATH_BOOLEAN(c, "x != x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c2/v = c3/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = c4/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "x = c1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x = x"), false); // empty node set compares as false with any other object via any comparison operator, as per XPath spec
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x != x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = c2/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = c3/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c2/v = c3/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = c4/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x = c1"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c2/v != c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != c4/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != c5/v", true); // (a, b) != (a, b), since a != b, as per XPath spec (comparison operators are so not intutive)
|
||||
CHECK_XPATH_BOOLEAN(n, "c3/v != c6/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "x != c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c2/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c3/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c2/v != c3/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c4/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c5/v"), true); // (a, b) != (a, b), since a != b, as per XPath spec (comparison operators are so not intutive)
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c3/v != c6/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x != c1/v"), false);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_operators_equality_node_set_primitive, "<node><c1><v>1</v><v>-1</v><v>100</v></c1><c2><v>1</v><v>nan</v></c2></node>")
|
||||
{
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// node set vs number
|
||||
CHECK_XPATH_BOOLEAN(c, "x = 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x != 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 = x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 != x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x = 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x != 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 = x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 != x"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = 1", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = -1", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != 1", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = 5", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c2/v = 1", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = 1"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = -1"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != 1"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = 5"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c2/v = 1"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "1 = c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "-1 = c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "1 != c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "5 = c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "1 = c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("1 = c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("-1 = c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("1 != c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("5 = c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("1 = c2/v"), true);
|
||||
|
||||
#ifndef MSVC6_NAN_BUG
|
||||
CHECK_XPATH_BOOLEAN(n, "c2/v != 1", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "1 != c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c2/v != 1"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("1 != c2/v"), true);
|
||||
#endif
|
||||
|
||||
// node set vs string
|
||||
CHECK_XPATH_BOOLEAN(c, "x = '1'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x != '1'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "'1' = x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "'1' != x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x = '1'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x != '1'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'1' = x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("'1' != x"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = '1'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = '-1'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != '1'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = '5'", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c2/v = '1'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c2/v != '1'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = '1'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = '-1'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != '1'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = '5'"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c2/v = '1'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c2/v != '1'"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "'1' = c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'-1' = c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'1' != c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'5' = c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "'1' = c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'1' != c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'1' = c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'-1' = c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'1' != c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'5' = c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'1' = c2/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'1' != c2/v"), true);
|
||||
|
||||
// node set vs almost-numeric string just in case
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = '1.0'", false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = '1.0'"), false);
|
||||
|
||||
// node set vs boolean - special rules! empty sets are equal to true()
|
||||
CHECK_XPATH_BOOLEAN(n, "x = true()", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "x != true()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "x = false()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = true()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v != true()", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v = false()", false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x = true()"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x != true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x = false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != true()"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v = false()"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "true() = x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "true() != x", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "false() = x", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "true() = c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "true() != c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "false() = c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("true() = x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("true() != x"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("false() = x"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("true() = c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("true() != c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("false() = c1/v"), false);
|
||||
}
|
||||
|
||||
TEST(xpath_operators_inequality_primitive)
|
||||
|
@ -263,143 +263,143 @@ TEST(xpath_operators_inequality_primitive)
|
|||
xml_node c;
|
||||
|
||||
// number vs number
|
||||
CHECK_XPATH_BOOLEAN(c, "1 < 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 <= 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 > 2", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 >= 2", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 < 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 <= 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 > 2"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 >= 2"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(c, "1 < 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 <= 1", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 > 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 >= 1", true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 < 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 <= 1"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 > 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 >= 1"), true);
|
||||
|
||||
// infinity/nan
|
||||
CHECK_XPATH_BOOLEAN(c, "1 div 0 <= 2 div 0", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 div 0 < 2 div 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "-1 div 0 < 2 div 0", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "-1 div 0 > 2 div 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 div 0 <= 2 div 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 div 0 < 2 div 0"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("-1 div 0 < 2 div 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("-1 div 0 > 2 div 0"), false);
|
||||
|
||||
#ifndef MSVC6_NAN_BUG
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 < 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 <= 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 > 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 div 0 >= 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 < 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 <= 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 > 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 div 0 >= 1"), false);
|
||||
#endif
|
||||
|
||||
// upcast to number
|
||||
CHECK_XPATH_BOOLEAN(c, "2 < '2'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 < '2'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 <= '2'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "3 <= '2'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 > '2'", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "3 > '2'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 >= '2'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "3 >= '2'", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 >= true()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 > true()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 < '2'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 < '2'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 <= '2'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("3 <= '2'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 > '2'"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("3 > '2'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 >= '2'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("3 >= '2'"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 >= true()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 > true()"), false);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_operators_inequality_node_set_node_set, "<node><c1><v>1</v><v>-1</v><v>-100</v></c1><c2><v>1</v><v>nan</v></c2><c3><v>1</v><v>-4</v></c3></node>")
|
||||
{
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// node set vs node set
|
||||
CHECK_XPATH_BOOLEAN(c, "x < x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x > x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x <= x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x >= x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x < x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x > x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x <= x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x >= x"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v < x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v >= x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v <= x", false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v < x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= x"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "x > c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "x < c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "x >= c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "x <= c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x > c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x < c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x >= c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x <= c1/v"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v >= c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v < c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v <= c3/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > c3/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= c3/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v < c3/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= c3/v"), true);
|
||||
|
||||
#ifndef MSVC6_NAN_BUG
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > c2/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v >= c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v < c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v <= c2/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > c2/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= c2/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v < c2/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= c2/v"), true);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_XML(xpath_operators_inequality_node_set_primitive, "<node><c1><v>1</v><v>-1</v><v>-100</v></c1><c2><v>1</v><v>nan</v></c2></node>")
|
||||
{
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// node set vs number
|
||||
CHECK_XPATH_BOOLEAN(c, "x < 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x > 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x <= 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "x >= 0", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x < 0"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x > 0"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x <= 0"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("x >= 0"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(c, "0 < x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 > x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 <= x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "0 >= x", false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 < x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 > x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 <= x"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("0 >= x"), false);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > 0", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > 1", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v >= 0", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v < 0", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v <= 0", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v < 0"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= 0"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "0 < c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "1 < c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "0 <= c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "0 > c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "0 >= c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("0 < c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("1 < c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("0 <= c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("0 > c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("0 >= c1/v"), true);
|
||||
|
||||
// node set vs string
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > '0'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > '1'", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v >= '0'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v < '0'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v <= '0'", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > '0'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > '1'"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= '0'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v < '0'"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= '0'"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "'0' < c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'1' < c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "'0' <= c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'0' > c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "'0' >= c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'0' < c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'1' < c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'0' <= c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'0' > c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("'0' >= c1/v"), true);
|
||||
|
||||
// node set vs boolean
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > false()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v > true()", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v >= false()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v < false()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "c1/v <= false()", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v > true()"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v < false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= false()"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(n, "false() < c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "true() < c1/v", false);
|
||||
CHECK_XPATH_BOOLEAN(n, "false() <= c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "false() > c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, "false() >= c1/v", true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("false() < c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("true() < c1/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("false() <= c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("false() > c1/v"), true);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("false() >= c1/v"), true);
|
||||
}
|
||||
|
||||
TEST(xpath_operators_boolean_precedence)
|
||||
{
|
||||
xml_node c;
|
||||
|
||||
CHECK_XPATH_BOOLEAN(c, "1 = 0 or 2 = 2", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 = (0 or 2) = false()", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "1 < 0 or 2 > 2", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 < 1 = false()", true);
|
||||
CHECK_XPATH_BOOLEAN(c, "2 < (1 = false())", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "3 > 2 > 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "(3 > 2) > 1", false);
|
||||
CHECK_XPATH_BOOLEAN(c, "3 > (2 > 1)", true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 = 0 or 2 = 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 = (0 or 2) = false()"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("1 < 0 or 2 > 2"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 < 1 = false()"), true);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("2 < (1 = false())"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("3 > 2 > 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("(3 > 2) > 1"), false);
|
||||
CHECK_XPATH_BOOLEAN(c, STR("3 > (2 > 1)"), true);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_operators_union, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/><tail/></node>")
|
||||
|
@ -407,15 +407,15 @@ TEST_XML(xpath_operators_union, "<node><employee/><employee secretary=''/><emplo
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "employee | .") % 2 % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@secretary] | employee[@assistant]") % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@assistant] | employee[@secretary]") % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@secretary] | employee[@nobody]") % 4 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@nobody] | employee[@secretary]") % 4 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "tail/preceding-sibling::employee | .") % 2 % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, ". | tail/preceding-sibling::employee | .") % 2 % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee | .")) % 2 % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@secretary] | employee[@assistant]")) % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@assistant] | employee[@secretary]")) % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@secretary] | employee[@nobody]")) % 4 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@nobody] | employee[@secretary]")) % 4 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("tail/preceding-sibling::employee | .")) % 2 % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR(". | tail/preceding-sibling::employee | .")) % 2 % 3 % 4 % 6 % 8 % 11;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,88 +5,88 @@
|
|||
TEST(xpath_literal_parse)
|
||||
{
|
||||
xml_node c;
|
||||
CHECK_XPATH_STRING(c, "'a\"b'", "a\"b");
|
||||
CHECK_XPATH_STRING(c, "\"a'b\"", "a'b");
|
||||
CHECK_XPATH_STRING(c, "\"\"", "");
|
||||
CHECK_XPATH_STRING(c, "\'\'", "");
|
||||
CHECK_XPATH_STRING(c, STR("'a\"b'"), STR("a\"b"));
|
||||
CHECK_XPATH_STRING(c, STR("\"a'b\""), STR("a'b"));
|
||||
CHECK_XPATH_STRING(c, STR("\"\""), STR(""));
|
||||
CHECK_XPATH_STRING(c, STR("\'\'"), STR(""));
|
||||
}
|
||||
|
||||
TEST(xpath_literal_error)
|
||||
{
|
||||
CHECK_XPATH_FAIL("\"");
|
||||
CHECK_XPATH_FAIL("\'");
|
||||
CHECK_XPATH_FAIL(STR("\""));
|
||||
CHECK_XPATH_FAIL(STR("\'"));
|
||||
}
|
||||
|
||||
TEST(xpath_number_parse)
|
||||
{
|
||||
xml_node c;
|
||||
CHECK_XPATH_NUMBER(c, "0", 0);
|
||||
CHECK_XPATH_NUMBER(c, "123", 123);
|
||||
CHECK_XPATH_NUMBER(c, "123.456", 123.456);
|
||||
CHECK_XPATH_NUMBER(c, ".123", 0.123);
|
||||
CHECK_XPATH_NUMBER(c, "123.4567890123456789012345", 123.4567890123456789012345);
|
||||
CHECK_XPATH_NUMBER(c, STR("0"), 0);
|
||||
CHECK_XPATH_NUMBER(c, STR("123"), 123);
|
||||
CHECK_XPATH_NUMBER(c, STR("123.456"), 123.456);
|
||||
CHECK_XPATH_NUMBER(c, STR(".123"), 0.123);
|
||||
CHECK_XPATH_NUMBER(c, STR("123.4567890123456789012345"), 123.4567890123456789012345);
|
||||
}
|
||||
|
||||
TEST(xpath_number_error)
|
||||
{
|
||||
CHECK_XPATH_FAIL("123a");
|
||||
CHECK_XPATH_FAIL("123.a");
|
||||
CHECK_XPATH_FAIL(".123a");
|
||||
CHECK_XPATH_FAIL(STR("123a"));
|
||||
CHECK_XPATH_FAIL(STR("123.a"));
|
||||
CHECK_XPATH_FAIL(STR(".123a"));
|
||||
}
|
||||
|
||||
TEST(xpath_variables)
|
||||
{
|
||||
CHECK_XPATH_FAIL("$var"); // not implemented
|
||||
CHECK_XPATH_FAIL("$1");
|
||||
CHECK_XPATH_FAIL(STR("$var")); // not implemented
|
||||
CHECK_XPATH_FAIL(STR("$1"));
|
||||
}
|
||||
|
||||
TEST(xpath_empty_expression)
|
||||
{
|
||||
CHECK_XPATH_FAIL("");
|
||||
CHECK_XPATH_FAIL(STR(""));
|
||||
}
|
||||
|
||||
TEST(xpath_lexer_error)
|
||||
{
|
||||
CHECK_XPATH_FAIL("!");
|
||||
CHECK_XPATH_FAIL("&");
|
||||
CHECK_XPATH_FAIL(STR("!"));
|
||||
CHECK_XPATH_FAIL(STR("&"));
|
||||
}
|
||||
|
||||
TEST(xpath_unmatched_braces)
|
||||
{
|
||||
CHECK_XPATH_FAIL("node[");
|
||||
CHECK_XPATH_FAIL("node[1");
|
||||
CHECK_XPATH_FAIL("node[]]");
|
||||
CHECK_XPATH_FAIL("node(");
|
||||
CHECK_XPATH_FAIL("node(()");
|
||||
CHECK_XPATH_FAIL("(node)[1");
|
||||
CHECK_XPATH_FAIL("(1");
|
||||
CHECK_XPATH_FAIL(STR("node["));
|
||||
CHECK_XPATH_FAIL(STR("node[1"));
|
||||
CHECK_XPATH_FAIL(STR("node[]]"));
|
||||
CHECK_XPATH_FAIL(STR("node("));
|
||||
CHECK_XPATH_FAIL(STR("node(()"));
|
||||
CHECK_XPATH_FAIL(STR("(node)[1"));
|
||||
CHECK_XPATH_FAIL(STR("(1"));
|
||||
}
|
||||
|
||||
TEST(xpath_incorrect_step)
|
||||
{
|
||||
CHECK_XPATH_FAIL("child::1");
|
||||
CHECK_XPATH_FAIL("something::*");
|
||||
CHECK_XPATH_FAIL("a::*");
|
||||
CHECK_XPATH_FAIL("c::*");
|
||||
CHECK_XPATH_FAIL("d::*");
|
||||
CHECK_XPATH_FAIL("f::*");
|
||||
CHECK_XPATH_FAIL("n::*");
|
||||
CHECK_XPATH_FAIL("p::*");
|
||||
CHECK_XPATH_FAIL(STR("child::1"));
|
||||
CHECK_XPATH_FAIL(STR("something::*"));
|
||||
CHECK_XPATH_FAIL(STR("a::*"));
|
||||
CHECK_XPATH_FAIL(STR("c::*"));
|
||||
CHECK_XPATH_FAIL(STR("d::*"));
|
||||
CHECK_XPATH_FAIL(STR("f::*"));
|
||||
CHECK_XPATH_FAIL(STR("n::*"));
|
||||
CHECK_XPATH_FAIL(STR("p::*"));
|
||||
}
|
||||
|
||||
TEST(xpath_semantics_error)
|
||||
{
|
||||
CHECK_XPATH_FAIL("1[1]");
|
||||
CHECK_XPATH_FAIL("1 | 1");
|
||||
CHECK_XPATH_FAIL(STR("1[1]"));
|
||||
CHECK_XPATH_FAIL(STR("1 | 1"));
|
||||
}
|
||||
|
||||
TEST(xpath_semantics_posinv) // coverage for contains()
|
||||
{
|
||||
xpath_query("(node)[substring(1, 2, 3)]");
|
||||
xpath_query("(node)[concat(1, 2, 3, 4)]");
|
||||
xpath_query("(node)[count(foo)]");
|
||||
xpath_query("(node)[local-name()]");
|
||||
xpath_query("(node)[(node)[1]]");
|
||||
xpath_query(STR("(node)[substring(1, 2, 3)]"));
|
||||
xpath_query(STR("(node)[concat(1, 2, 3, 4)]"));
|
||||
xpath_query(STR("(node)[count(foo)]"));
|
||||
xpath_query(STR("(node)[local-name()]"));
|
||||
xpath_query(STR("(node)[(node)[1]]"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,12 +7,12 @@ TEST_XML(xpath_paths_axes_child, "<node attr='value'><child attr='value'><subchi
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("child:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "child:: node()") % 4 % 7 % 8; // child, another, last
|
||||
CHECK_XPATH_NODESET(n, "another/child:: node()");
|
||||
CHECK_XPATH_NODESET(n, STR("child:: node()")) % 4 % 7 % 8; // child, another, last
|
||||
CHECK_XPATH_NODESET(n, STR("another/child:: node()"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_descendant, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -20,14 +20,14 @@ TEST_XML(xpath_paths_axes_descendant, "<node attr='value'><child attr='value'><s
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "descendant:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("descendant:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "descendant:: node()") % 4 % 6 % 7 % 8 % 9; // child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(doc, "descendant:: node()") % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, "another/descendant:: node()") % 8; // subchild
|
||||
CHECK_XPATH_NODESET(n, "last/descendant:: node()");
|
||||
CHECK_XPATH_NODESET(n, STR("descendant:: node()")) % 4 % 6 % 7 % 8 % 9; // child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(doc, STR("descendant:: node()")) % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, STR("another/descendant:: node()")) % 8; // subchild
|
||||
CHECK_XPATH_NODESET(n, STR("last/descendant:: node()"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_parent, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -35,15 +35,15 @@ TEST_XML(xpath_paths_axes_parent, "<node attr='value'><child attr='value'><subch
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "parent:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("parent:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "parent:: node()") % 2; // node
|
||||
CHECK_XPATH_NODESET(n, "child/subchild/parent:: node()") % 4; // child
|
||||
CHECK_XPATH_NODESET(n, "@attr/parent:: node()") % 2; // node
|
||||
CHECK_XPATH_NODESET(n, "parent:: node()") % 1; // root
|
||||
CHECK_XPATH_NODESET(doc, "parent:: node()");
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("parent:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/parent:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("@attr/parent:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("parent:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(doc, STR("parent:: node()"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_ancestor, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -51,15 +51,15 @@ TEST_XML(xpath_paths_axes_ancestor, "<node attr='value'><child attr='value'><sub
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "ancestor:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("ancestor:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "ancestor:: node()") % 2 % 1; // node, root
|
||||
CHECK_XPATH_NODESET(n, "child/subchild/ancestor:: node()") % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, "child/@attr/ancestor:: node()") % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, "ancestor:: node()") % 1; // root
|
||||
CHECK_XPATH_NODESET(doc, "ancestor:: node()");
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("ancestor:: node()")) % 2 % 1; // node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(doc, STR("ancestor:: node()"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_following_sibling, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -67,13 +67,13 @@ TEST_XML(xpath_paths_axes_following_sibling, "<node attr1='value' attr2='value'>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "following-sibling:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("following-sibling:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "following-sibling:: node()") % 8 % 10; // another, last
|
||||
CHECK_XPATH_NODESET(n.child("last"), "following-sibling:: node()");
|
||||
CHECK_XPATH_NODESET(n, "@attr1/following-sibling:: node()"); // attributes are not siblings
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("following-sibling:: node()")) % 8 % 10; // another, last
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("following-sibling:: node()"));
|
||||
CHECK_XPATH_NODESET(n, STR("@attr1/following-sibling:: node()")); // attributes are not siblings
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_preceding_sibling, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -81,13 +81,13 @@ TEST_XML(xpath_paths_axes_preceding_sibling, "<node attr1='value' attr2='value'>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "preceding-sibling:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("preceding-sibling:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "preceding-sibling:: node()");
|
||||
CHECK_XPATH_NODESET(n.child("last"), "preceding-sibling:: node()") % 8 % 5; // another, child
|
||||
CHECK_XPATH_NODESET(n, "@attr2/following-sibling:: node()"); // attributes are not siblings
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("preceding-sibling:: node()"));
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("preceding-sibling:: node()")) % 8 % 5; // another, child
|
||||
CHECK_XPATH_NODESET(n, STR("@attr2/following-sibling:: node()")); // attributes are not siblings
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_following, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild/></another><almost/><last/></node>")
|
||||
|
@ -95,14 +95,14 @@ TEST_XML(xpath_paths_axes_following, "<node attr1='value' attr2='value'><child a
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "following:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("following:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "following:: node()"); // no descendants
|
||||
CHECK_XPATH_NODESET(n.child("child"), "following:: node()") % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n.child("child").child("subchild"), "following:: node()") % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n.child("last"), "following:: node()");
|
||||
CHECK_XPATH_NODESET(n, STR("following:: node()")); // no descendants
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("following:: node()")) % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")).child(STR("subchild")), STR("following:: node()")) % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("following:: node()"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_preceding, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild/></another><almost/><last/></node>")
|
||||
|
@ -110,14 +110,14 @@ TEST_XML(xpath_paths_axes_preceding, "<node attr1='value' attr2='value'><child a
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "preceding:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("preceding:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "preceding:: node()"); // no ancestors
|
||||
CHECK_XPATH_NODESET(n.child("last"), "preceding:: node()") % 10 % 9 % 8 % 7 % 5; // almost, subchild, another, subchild, child
|
||||
CHECK_XPATH_NODESET(n.child("another").child("subchild"), "preceding:: node()") % 7 % 5; // subchild, child
|
||||
CHECK_XPATH_NODESET(n, "preceding:: node()");
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("preceding:: node()")); // no ancestors
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("preceding:: node()")) % 10 % 9 % 8 % 7 % 5; // almost, subchild, another, subchild, child
|
||||
CHECK_XPATH_NODESET(n.child(STR("another")).child(STR("subchild")), STR("preceding:: node()")) % 7 % 5; // subchild, child
|
||||
CHECK_XPATH_NODESET(n, STR("preceding:: node()"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_attribute, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another xmlns:foo='bar'><subchild/></another><last/></node>")
|
||||
|
@ -125,22 +125,22 @@ TEST_XML(xpath_paths_axes_attribute, "<node attr1='value' attr2='value'><child a
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "attribute:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("attribute:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "attribute:: node()") % 6; // child/@attr
|
||||
CHECK_XPATH_NODESET(n.child("last"), "attribute:: node()");
|
||||
CHECK_XPATH_NODESET(n, "attribute:: node()") % 3 % 4; // node/@attr1 node/@attr2
|
||||
CHECK_XPATH_NODESET(doc, "descendant-or-self:: node()/attribute:: node()") % 3 % 4 % 6; // all attributes
|
||||
CHECK_XPATH_NODESET(n.child("another"), "attribute:: node()"); // namespace nodes are not attributes
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("attribute:: node()")) % 6; // child/@attr
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("attribute:: node()"));
|
||||
CHECK_XPATH_NODESET(n, STR("attribute:: node()")) % 3 % 4; // node/@attr1 node/@attr2
|
||||
CHECK_XPATH_NODESET(doc, STR("descendant-or-self:: node()/attribute:: node()")) % 3 % 4 % 6; // all attributes
|
||||
CHECK_XPATH_NODESET(n.child(STR("another")), STR("attribute:: node()")); // namespace nodes are not attributes
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_namespace, "<node xmlns:foo='bar'/>")
|
||||
{
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "namespace:: node()"); // namespace nodes are not supported
|
||||
CHECK_XPATH_NODESET(n, STR("namespace:: node()")); // namespace nodes are not supported
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_self, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -148,15 +148,15 @@ TEST_XML(xpath_paths_axes_self, "<node attr='value'><child attr='value'><subchil
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "self:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("self:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "self:: node()") % 4; // child
|
||||
CHECK_XPATH_NODESET(n, "self:: node()") % 2; // node
|
||||
CHECK_XPATH_NODESET(n, "child/self:: node()") % 4; // child
|
||||
CHECK_XPATH_NODESET(n, "child/@attr/self:: node()") % 5; // @attr
|
||||
CHECK_XPATH_NODESET(doc, "self:: node()") % 1; // root
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("self:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("self:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("child/self:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/self:: node()")) % 5; // @attr
|
||||
CHECK_XPATH_NODESET(doc, STR("self:: node()")) % 1; // root
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_descendant_or_self, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -164,14 +164,14 @@ TEST_XML(xpath_paths_axes_descendant_or_self, "<node attr='value'><child attr='v
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "descendant-or-self:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("descendant-or-self:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "descendant-or-self:: node()") % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(doc, "descendant-or-self:: node()") % 1 % 2 % 4 % 6 % 7 % 8 % 9; // root, node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, "another/descendant-or-self:: node()") % 7 % 8; // another, subchild
|
||||
CHECK_XPATH_NODESET(n, "last/descendant-or-self:: node()") % 9; // last
|
||||
CHECK_XPATH_NODESET(n, STR("descendant-or-self:: node()")) % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(doc, STR("descendant-or-self:: node()")) % 1 % 2 % 4 % 6 % 7 % 8 % 9; // root, node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, STR("another/descendant-or-self:: node()")) % 7 % 8; // another, subchild
|
||||
CHECK_XPATH_NODESET(n, STR("last/descendant-or-self:: node()")) % 9; // last
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_ancestor_or_self, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -179,15 +179,15 @@ TEST_XML(xpath_paths_axes_ancestor_or_self, "<node attr='value'><child attr='val
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "ancestor-or-self:: node()");
|
||||
CHECK_XPATH_NODESET(c, STR("ancestor-or-self:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child("child"), "ancestor-or-self:: node()") % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, "child/subchild/ancestor-or-self:: node()") % 6 % 4 % 2 % 1; // subchild, child, node, root
|
||||
CHECK_XPATH_NODESET(n, "child/@attr/ancestor-or-self:: node()") % 5 % 4 % 2 % 1; // @attr, child, node, root
|
||||
CHECK_XPATH_NODESET(n, "ancestor-or-self:: node()") % 2 % 1; // root, node
|
||||
CHECK_XPATH_NODESET(doc, "ancestor-or-self:: node()") % 1; // root
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("ancestor-or-self:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/ancestor-or-self:: node()")) % 6 % 4 % 2 % 1; // subchild, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/ancestor-or-self:: node()")) % 5 % 4 % 2 % 1; // @attr, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor-or-self:: node()")) % 2 % 1; // root, node
|
||||
CHECK_XPATH_NODESET(doc, STR("ancestor-or-self:: node()")) % 1; // root
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_abbrev, "<node attr='value'><foo/></node>")
|
||||
|
@ -195,20 +195,20 @@ TEST_XML(xpath_paths_axes_abbrev, "<node attr='value'><foo/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// @ axis
|
||||
CHECK_XPATH_NODESET(c, "@attr");
|
||||
CHECK_XPATH_NODESET(n, "@attr") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("@attr"));
|
||||
CHECK_XPATH_NODESET(n, STR("@attr")) % 3;
|
||||
|
||||
// no axis - child implied
|
||||
CHECK_XPATH_NODESET(c, "foo");
|
||||
CHECK_XPATH_NODESET(n, "foo") % 4;
|
||||
CHECK_XPATH_NODESET(doc, "node()") % 2;
|
||||
CHECK_XPATH_NODESET(c, STR("foo"));
|
||||
CHECK_XPATH_NODESET(n, STR("foo")) % 4;
|
||||
CHECK_XPATH_NODESET(doc, STR("node()")) % 2;
|
||||
|
||||
// @ axis should disable all other axis specifiers
|
||||
CHECK_XPATH_FAIL("@child::foo");
|
||||
CHECK_XPATH_FAIL("@attribute::foo");
|
||||
CHECK_XPATH_FAIL(STR("@child::foo"));
|
||||
CHECK_XPATH_FAIL(STR("@attribute::foo"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_nodetest_all, "<node a1='v1' x:a2='v2'><c1/><x:c2/><c3/><x:c4/></node>")
|
||||
|
@ -216,14 +216,14 @@ TEST_XML(xpath_paths_nodetest_all, "<node a1='v1' x:a2='v2'><c1/><x:c2/><c3/><x:
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "*");
|
||||
CHECK_XPATH_NODESET(c, "child::*");
|
||||
CHECK_XPATH_NODESET(c, STR("*"));
|
||||
CHECK_XPATH_NODESET(c, STR("child::*"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "*") % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(n, "child::*") % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(n, "attribute::*") % 3 % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("*")) % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(n, STR("child::*")) % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(n, STR("attribute::*")) % 3 % 4;
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(xpath_paths_nodetest_name, "<node a1='v1' x:a2='v2'><c1/><x:c2/><c3/><x:c4/><?c1?></node>", parse_default | parse_pi)
|
||||
|
@ -231,20 +231,20 @@ TEST_XML_FLAGS(xpath_paths_nodetest_name, "<node a1='v1' x:a2='v2'><c1/><x:c2/><
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "c1");
|
||||
CHECK_XPATH_NODESET(c, "child::c1");
|
||||
CHECK_XPATH_NODESET(c, STR("c1"));
|
||||
CHECK_XPATH_NODESET(c, STR("child::c1"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "c1") % 5;
|
||||
CHECK_XPATH_NODESET(n, "x:c2") % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("c1")) % 5;
|
||||
CHECK_XPATH_NODESET(n, STR("x:c2")) % 6;
|
||||
|
||||
CHECK_XPATH_NODESET(n, "child::c1") % 5;
|
||||
CHECK_XPATH_NODESET(n, "child::x:c2") % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("child::c1")) % 5;
|
||||
CHECK_XPATH_NODESET(n, STR("child::x:c2")) % 6;
|
||||
|
||||
CHECK_XPATH_NODESET(n, "attribute::a1") % 3;
|
||||
CHECK_XPATH_NODESET(n, "attribute::x:a2") % 4;
|
||||
CHECK_XPATH_NODESET(n, "@x:a2") % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("attribute::a1")) % 3;
|
||||
CHECK_XPATH_NODESET(n, STR("attribute::x:a2")) % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("@x:a2")) % 4;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_nodetest_all_in_namespace, "<node a1='v1' x:a2='v2'><c1/><x:c2/><c3/><x:c4/></node>")
|
||||
|
@ -252,19 +252,19 @@ TEST_XML(xpath_paths_nodetest_all_in_namespace, "<node a1='v1' x:a2='v2'><c1/><x
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "x:*");
|
||||
CHECK_XPATH_NODESET(c, "child::x:*");
|
||||
CHECK_XPATH_NODESET(c, STR("x:*"));
|
||||
CHECK_XPATH_NODESET(c, STR("child::x:*"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "x:*") % 6 % 8;
|
||||
CHECK_XPATH_NODESET(n, "child::x:*") % 6 % 8;
|
||||
CHECK_XPATH_NODESET(n, STR("x:*")) % 6 % 8;
|
||||
CHECK_XPATH_NODESET(n, STR("child::x:*")) % 6 % 8;
|
||||
|
||||
CHECK_XPATH_NODESET(n, "attribute::x:*") % 4;
|
||||
CHECK_XPATH_NODESET(n, "@x:*") % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("attribute::x:*")) % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("@x:*")) % 4;
|
||||
|
||||
CHECK_XPATH_FAIL(":*");
|
||||
CHECK_XPATH_FAIL("@:*");
|
||||
CHECK_XPATH_FAIL(STR(":*"));
|
||||
CHECK_XPATH_FAIL(STR("@:*"));
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(xpath_paths_nodetest_type, "<node attr='value'>pcdata<child/><?pi1 value?><?pi2 value?><!--comment--><![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments)
|
||||
|
@ -272,35 +272,35 @@ TEST_XML_FLAGS(xpath_paths_nodetest_type, "<node attr='value'>pcdata<child/><?pi
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
// check on empty nodes
|
||||
CHECK_XPATH_NODESET(c, "node()");
|
||||
CHECK_XPATH_NODESET(c, "text()");
|
||||
CHECK_XPATH_NODESET(c, "comment()");
|
||||
CHECK_XPATH_NODESET(c, "processing-instruction()");
|
||||
CHECK_XPATH_NODESET(c, "processing-instruction('foobar')");
|
||||
CHECK_XPATH_NODESET(c, STR("node()"));
|
||||
CHECK_XPATH_NODESET(c, STR("text()"));
|
||||
CHECK_XPATH_NODESET(c, STR("comment()"));
|
||||
CHECK_XPATH_NODESET(c, STR("processing-instruction()"));
|
||||
CHECK_XPATH_NODESET(c, STR("processing-instruction('foobar')"));
|
||||
|
||||
// child axis
|
||||
CHECK_XPATH_NODESET(n, "node()") % 4 % 5 % 6 % 7 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(n, "text()") % 4 % 9;
|
||||
CHECK_XPATH_NODESET(n, "comment()") % 8;
|
||||
CHECK_XPATH_NODESET(n, "processing-instruction()") % 6 % 7;
|
||||
CHECK_XPATH_NODESET(n, "processing-instruction('pi2')") % 7;
|
||||
CHECK_XPATH_NODESET(n, STR("node()")) % 4 % 5 % 6 % 7 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(n, STR("text()")) % 4 % 9;
|
||||
CHECK_XPATH_NODESET(n, STR("comment()")) % 8;
|
||||
CHECK_XPATH_NODESET(n, STR("processing-instruction()")) % 6 % 7;
|
||||
CHECK_XPATH_NODESET(n, STR("processing-instruction('pi2')")) % 7;
|
||||
|
||||
// attribute axis
|
||||
CHECK_XPATH_NODESET(n, "@node()") % 3;
|
||||
CHECK_XPATH_NODESET(n, "@text()");
|
||||
CHECK_XPATH_NODESET(n, "@comment()");
|
||||
CHECK_XPATH_NODESET(n, "@processing-instruction()");
|
||||
CHECK_XPATH_NODESET(n, "@processing-instruction('pi2')");
|
||||
CHECK_XPATH_NODESET(n, STR("@node()")) % 3;
|
||||
CHECK_XPATH_NODESET(n, STR("@text()"));
|
||||
CHECK_XPATH_NODESET(n, STR("@comment()"));
|
||||
CHECK_XPATH_NODESET(n, STR("@processing-instruction()"));
|
||||
CHECK_XPATH_NODESET(n, STR("@processing-instruction('pi2')"));
|
||||
|
||||
// incorrect 'argument' number
|
||||
CHECK_XPATH_FAIL("node('')");
|
||||
CHECK_XPATH_FAIL("text('')");
|
||||
CHECK_XPATH_FAIL("comment('')");
|
||||
CHECK_XPATH_FAIL("processing-instruction(1)");
|
||||
CHECK_XPATH_FAIL("processing-instruction('', '')");
|
||||
CHECK_XPATH_FAIL(STR("node('')"));
|
||||
CHECK_XPATH_FAIL(STR("text('')"));
|
||||
CHECK_XPATH_FAIL(STR("comment('')"));
|
||||
CHECK_XPATH_FAIL(STR("processing-instruction(1)"));
|
||||
CHECK_XPATH_FAIL(STR("processing-instruction('', '')"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_absolute, "<node><foo><foo/><foo/></foo></node>")
|
||||
|
@ -308,16 +308,16 @@ TEST_XML(xpath_paths_absolute, "<node><foo><foo/><foo/></foo></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/foo");
|
||||
CHECK_XPATH_NODESET(n, "/foo");
|
||||
CHECK_XPATH_NODESET(n, "/node/foo") % 3;
|
||||
CHECK_XPATH_NODESET(n.child("foo"), "/node/foo") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("/foo"));
|
||||
CHECK_XPATH_NODESET(n, STR("/foo"));
|
||||
CHECK_XPATH_NODESET(n, STR("/node/foo")) % 3;
|
||||
CHECK_XPATH_NODESET(n.child(STR("foo")), STR("/node/foo")) % 3;
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/");
|
||||
CHECK_XPATH_NODESET(n, "/") % 1;
|
||||
CHECK_XPATH_NODESET(n.child("foo"), "/") % 1;
|
||||
CHECK_XPATH_NODESET(c, STR("/"));
|
||||
CHECK_XPATH_NODESET(n, STR("/")) % 1;
|
||||
CHECK_XPATH_NODESET(n.child(STR("foo")), STR("/")) % 1;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_step_abbrev, "<node><foo/></node>")
|
||||
|
@ -325,18 +325,18 @@ TEST_XML(xpath_paths_step_abbrev, "<node><foo/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, ".");
|
||||
CHECK_XPATH_NODESET(c, "..");
|
||||
CHECK_XPATH_NODESET(c, STR("."));
|
||||
CHECK_XPATH_NODESET(c, STR(".."));
|
||||
|
||||
CHECK_XPATH_NODESET(n, ".") % 2;
|
||||
CHECK_XPATH_NODESET(n, "..") % 1;
|
||||
CHECK_XPATH_NODESET(n, "../node") % 2;
|
||||
CHECK_XPATH_NODESET(n.child("foo"), "..") % 2;
|
||||
CHECK_XPATH_NODESET(n, STR(".")) % 2;
|
||||
CHECK_XPATH_NODESET(n, STR("..")) % 1;
|
||||
CHECK_XPATH_NODESET(n, STR("../node")) % 2;
|
||||
CHECK_XPATH_NODESET(n.child(STR("foo")), STR("..")) % 2;
|
||||
|
||||
CHECK_XPATH_FAIL(".node");
|
||||
CHECK_XPATH_FAIL("..node");
|
||||
CHECK_XPATH_FAIL(STR(".node"));
|
||||
CHECK_XPATH_FAIL(STR("..node"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_relative_abbrev, "<node><foo><foo/><foo/></foo></node>")
|
||||
|
@ -344,13 +344,13 @@ TEST_XML(xpath_paths_relative_abbrev, "<node><foo><foo/><foo/></foo></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "foo//bar");
|
||||
CHECK_XPATH_NODESET(c, STR("foo//bar"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "foo/foo") % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n, "foo//foo") % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n, ".//foo") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n, STR("foo/foo")) % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n, STR("foo//foo")) % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n, STR(".//foo")) % 3 % 4 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_absolute_abbrev, "<node><foo><foo/><foo/></foo></node>")
|
||||
|
@ -358,117 +358,117 @@ TEST_XML(xpath_paths_absolute_abbrev, "<node><foo><foo/><foo/></foo></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "//bar");
|
||||
CHECK_XPATH_NODESET(c, STR("//bar"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "//foo") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n.child("foo"), "//foo") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(doc, "//foo") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n, STR("//foo")) % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(n.child(STR("foo")), STR("//foo")) % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(doc, STR("//foo")) % 3 % 4 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_predicate_boolean, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
|
||||
xml_node n = doc.child(STR("node")).child(STR("chapter")).next_sibling().next_sibling();
|
||||
|
||||
CHECK_XPATH_NODESET(n, "following-sibling::chapter[position()=1]") % 6;
|
||||
CHECK_XPATH_NODESET(n, "following-sibling::chapter[position()=2]") % 7;
|
||||
CHECK_XPATH_NODESET(n, "preceding-sibling::chapter[position()=1]") % 4;
|
||||
CHECK_XPATH_NODESET(n, "preceding-sibling::chapter[position()=2]") % 3;
|
||||
CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[position()=1]")) % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[position()=2]")) % 7;
|
||||
CHECK_XPATH_NODESET(n, STR("preceding-sibling::chapter[position()=1]")) % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("preceding-sibling::chapter[position()=2]")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_predicate_number, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
|
||||
xml_node n = doc.child(STR("node")).child(STR("chapter")).next_sibling().next_sibling();
|
||||
|
||||
CHECK_XPATH_NODESET(n, "following-sibling::chapter[1]") % 6;
|
||||
CHECK_XPATH_NODESET(n, "following-sibling::chapter[2]") % 7;
|
||||
CHECK_XPATH_NODESET(n, "preceding-sibling::chapter[1]") % 4;
|
||||
CHECK_XPATH_NODESET(n, "preceding-sibling::chapter[2]") % 3;
|
||||
CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[1]")) % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[2]")) % 7;
|
||||
CHECK_XPATH_NODESET(n, STR("preceding-sibling::chapter[1]")) % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("preceding-sibling::chapter[2]")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_predicate_several, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "employee") % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@secretary]") % 4 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@assistant]") % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@secretary][@assistant]") % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@assistant][@secretary]") % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "employee[@secretary and @assistant]") % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee")) % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@secretary]")) % 4 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@assistant]")) % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@secretary][@assistant]")) % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@assistant][@secretary]")) % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@secretary and @assistant]")) % 8 % 11;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_predicate_filter_boolean, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
|
||||
xml_node n = doc.child(STR("node")).child(STR("chapter")).next_sibling().next_sibling();
|
||||
|
||||
CHECK_XPATH_NODESET(n, "(following-sibling::chapter)[position()=1]") % 6;
|
||||
CHECK_XPATH_NODESET(n, "(following-sibling::chapter)[position()=2]") % 7;
|
||||
CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[position()=1]") % 3;
|
||||
CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[position()=2]") % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("(following-sibling::chapter)[position()=1]")) % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("(following-sibling::chapter)[position()=2]")) % 7;
|
||||
CHECK_XPATH_NODESET(n, STR("(preceding-sibling::chapter)[position()=1]")) % 3;
|
||||
CHECK_XPATH_NODESET(n, STR("(preceding-sibling::chapter)[position()=2]")) % 4;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_predicate_filter_number, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
|
||||
xml_node n = doc.child(STR("node")).child(STR("chapter")).next_sibling().next_sibling();
|
||||
|
||||
CHECK_XPATH_NODESET(n, "(following-sibling::chapter)[1]") % 6;
|
||||
CHECK_XPATH_NODESET(n, "(following-sibling::chapter)[2]") % 7;
|
||||
CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[1]") % 3;
|
||||
CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[2]") % 4;
|
||||
CHECK_XPATH_NODESET(n, STR("(following-sibling::chapter)[1]")) % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("(following-sibling::chapter)[2]")) % 7;
|
||||
CHECK_XPATH_NODESET(n, STR("(preceding-sibling::chapter)[1]")) % 3;
|
||||
CHECK_XPATH_NODESET(n, STR("(preceding-sibling::chapter)[2]")) % 4;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_predicate_filter_posinv, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "employee") % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "(employee[@secretary])[@assistant]") % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, "((employee)[@assistant])[@secretary]") % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("employee")) % 3 % 4 % 6 % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("(employee[@secretary])[@assistant]")) % 8 % 11;
|
||||
CHECK_XPATH_NODESET(n, STR("((employee)[@assistant])[@secretary]")) % 8 % 11;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_step_compose, "<node><foo><foo/><foo/></foo><foo/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, "(.)/foo") % 3 % 6;
|
||||
CHECK_XPATH_NODESET(n, "(.)//foo") % 3 % 4 % 5 % 6;
|
||||
CHECK_XPATH_NODESET(n, "(./..)//*") % 2 % 3 % 4 % 5 % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("(.)/foo")) % 3 % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("(.)//foo")) % 3 % 4 % 5 % 6;
|
||||
CHECK_XPATH_NODESET(n, STR("(./..)//*")) % 2 % 3 % 4 % 5 % 6;
|
||||
|
||||
CHECK_XPATH_FAIL("(1)/foo");
|
||||
CHECK_XPATH_FAIL("(1)//foo");
|
||||
CHECK_XPATH_FAIL(STR("(1)/foo"));
|
||||
CHECK_XPATH_FAIL(STR("(1)//foo"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_descendant_double_slash_w3c, "<node><para><para/><para/><para><para/></para></para><para/></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
CHECK_XPATH_NODESET(doc, "//para") % 3 % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(doc, "/descendant::para") % 3 % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(doc, "//para[1]") % 3 % 4 % 7;
|
||||
CHECK_XPATH_NODESET(doc, "/descendant::para[1]") % 3;
|
||||
CHECK_XPATH_NODESET(doc, STR("//para")) % 3 % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(doc, STR("/descendant::para")) % 3 % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(doc, STR("//para[1]")) % 3 % 4 % 7;
|
||||
CHECK_XPATH_NODESET(doc, STR("/descendant::para[1]")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_needs_sorting, "<node><child/><child/><child><subchild/><subchild/></child></node>")
|
||||
{
|
||||
doc.precompute_document_order();
|
||||
|
||||
CHECK_XPATH_NODESET(doc, "(node/child/subchild)[2]") % 7;
|
||||
CHECK_XPATH_NODESET(doc, STR("(node/child/subchild)[2]")) % 7;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,10 +7,10 @@ TEST_XML(xpath_paths_abbrev_w3c_1, "<node><para/><foo/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para");
|
||||
CHECK_XPATH_NODESET(n, "para") % 3 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("para"));
|
||||
CHECK_XPATH_NODESET(n, STR("para")) % 3 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_2, "<node><para/><foo/><para/></node>")
|
||||
|
@ -18,10 +18,10 @@ TEST_XML(xpath_paths_abbrev_w3c_2, "<node><para/><foo/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "*");
|
||||
CHECK_XPATH_NODESET(n, "*") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("*"));
|
||||
CHECK_XPATH_NODESET(n, STR("*")) % 3 % 4 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_3, "<node>pcdata<child/><![CDATA[cdata]]></node>")
|
||||
|
@ -29,10 +29,10 @@ TEST_XML(xpath_paths_abbrev_w3c_3, "<node>pcdata<child/><![CDATA[cdata]]></node>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "text()");
|
||||
CHECK_XPATH_NODESET(n, "text()") % 3 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("text()"));
|
||||
CHECK_XPATH_NODESET(n, STR("text()")) % 3 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_4, "<node name='value' foo='bar' />")
|
||||
|
@ -40,10 +40,10 @@ TEST_XML(xpath_paths_abbrev_w3c_4, "<node name='value' foo='bar' />")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "@name");
|
||||
CHECK_XPATH_NODESET(n, "@name") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("@name"));
|
||||
CHECK_XPATH_NODESET(n, STR("@name")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_5, "<node name='value' foo='bar' />")
|
||||
|
@ -51,10 +51,10 @@ TEST_XML(xpath_paths_abbrev_w3c_5, "<node name='value' foo='bar' />")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "@*");
|
||||
CHECK_XPATH_NODESET(n, "@*") % 3 % 4;
|
||||
CHECK_XPATH_NODESET(c, STR("@*"));
|
||||
CHECK_XPATH_NODESET(n, STR("@*")) % 3 % 4;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_6, "<node><para/><para/><para/><para/></node>")
|
||||
|
@ -62,10 +62,10 @@ TEST_XML(xpath_paths_abbrev_w3c_6, "<node><para/><para/><para/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para[1]");
|
||||
CHECK_XPATH_NODESET(n, "para[1]") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("para[1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("para[1]")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_7, "<node><para/><para/><para/><para/></node>")
|
||||
|
@ -73,10 +73,10 @@ TEST_XML(xpath_paths_abbrev_w3c_7, "<node><para/><para/><para/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para[last()]");
|
||||
CHECK_XPATH_NODESET(n, "para[last()]") % 6;
|
||||
CHECK_XPATH_NODESET(c, STR("para[last()]"));
|
||||
CHECK_XPATH_NODESET(n, STR("para[last()]")) % 6;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_8, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -85,8 +85,8 @@ TEST_XML(xpath_paths_abbrev_w3c_8, "<node><para><para/><para/><foo><para/></foo>
|
|||
|
||||
xml_node c;
|
||||
|
||||
CHECK_XPATH_NODESET(c, "*/para");
|
||||
CHECK_XPATH_NODESET(doc, "*/para") % 3 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("*/para"));
|
||||
CHECK_XPATH_NODESET(doc, STR("*/para")) % 3 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_9, "<doc><chapter/><chapter/><chapter/><chapter/><chapter><section/><section/><section/></chapter><chapter/></doc>")
|
||||
|
@ -94,11 +94,11 @@ TEST_XML(xpath_paths_abbrev_w3c_9, "<doc><chapter/><chapter/><chapter/><chapter/
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("doc").child("chapter");
|
||||
xml_node n = doc.child(STR("doc")).child(STR("chapter"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/doc/chapter[5]/section[2]");
|
||||
CHECK_XPATH_NODESET(n, "/doc/chapter[5]/section[2]") % 9;
|
||||
CHECK_XPATH_NODESET(doc, "/doc/chapter[5]/section[2]") % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("/doc/chapter[5]/section[2]"));
|
||||
CHECK_XPATH_NODESET(n, STR("/doc/chapter[5]/section[2]")) % 9;
|
||||
CHECK_XPATH_NODESET(doc, STR("/doc/chapter[5]/section[2]")) % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_10, "<chapter><para><para/><para/><foo><para/></foo></para><foo/><para/></chapter>")
|
||||
|
@ -107,8 +107,8 @@ TEST_XML(xpath_paths_abbrev_w3c_10, "<chapter><para><para/><para/><foo><para/></
|
|||
|
||||
xml_node c;
|
||||
|
||||
CHECK_XPATH_NODESET(c, "chapter//para");
|
||||
CHECK_XPATH_NODESET(doc, "chapter//para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("chapter//para"));
|
||||
CHECK_XPATH_NODESET(doc, STR("chapter//para")) % 3 % 4 % 5 % 7 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_11, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -116,11 +116,11 @@ TEST_XML(xpath_paths_abbrev_w3c_11, "<node><para><para/><para/><foo><para/></foo
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "//para");
|
||||
CHECK_XPATH_NODESET(n, "//para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("para"), "//para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("//para"));
|
||||
CHECK_XPATH_NODESET(n, STR("//para")) % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR("//para")) % 3 % 4 % 5 % 7 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_12, "<node><olist><item/></olist><item/><olist><olist><item/><item/></olist></olist></node>")
|
||||
|
@ -128,11 +128,11 @@ TEST_XML(xpath_paths_abbrev_w3c_12, "<node><olist><item/></olist><item/><olist><
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "//olist/item");
|
||||
CHECK_XPATH_NODESET(n, "//olist/item") % 4 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("olist"), "//olist/item") % 4 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("//olist/item"));
|
||||
CHECK_XPATH_NODESET(n, STR("//olist/item")) % 4 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("olist")), STR("//olist/item")) % 4 % 8 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_13, "<node><child/></node>")
|
||||
|
@ -140,11 +140,11 @@ TEST_XML(xpath_paths_abbrev_w3c_13, "<node><child/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, ".");
|
||||
CHECK_XPATH_NODESET(n, ".") % 2;
|
||||
CHECK_XPATH_NODESET(n.child("child"), ".") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("."));
|
||||
CHECK_XPATH_NODESET(n, STR(".")) % 2;
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR(".")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_14, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -152,11 +152,11 @@ TEST_XML(xpath_paths_abbrev_w3c_14, "<node><para><para/><para/><foo><para/></foo
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, ".//para");
|
||||
CHECK_XPATH_NODESET(n, ".//para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("para"), ".//para") % 4 % 5 % 7;
|
||||
CHECK_XPATH_NODESET(c, STR(".//para"));
|
||||
CHECK_XPATH_NODESET(n, STR(".//para")) % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR(".//para")) % 4 % 5 % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_15, "<node lang='en'><child/></node>")
|
||||
|
@ -164,11 +164,11 @@ TEST_XML(xpath_paths_abbrev_w3c_15, "<node lang='en'><child/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "..");
|
||||
CHECK_XPATH_NODESET(n, "..") % 1;
|
||||
CHECK_XPATH_NODESET(n.child("child"), "..") % 2;
|
||||
CHECK_XPATH_NODESET(c, STR(".."));
|
||||
CHECK_XPATH_NODESET(n, STR("..")) % 1;
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("..")) % 2;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_16, "<node lang='en'><child/></node>")
|
||||
|
@ -176,11 +176,11 @@ TEST_XML(xpath_paths_abbrev_w3c_16, "<node lang='en'><child/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "../@lang");
|
||||
CHECK_XPATH_NODESET(n, "../@lang");
|
||||
CHECK_XPATH_NODESET(n.child("child"), "../@lang") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("../@lang"));
|
||||
CHECK_XPATH_NODESET(n, STR("../@lang"));
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("../@lang")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_17, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='error'/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -188,10 +188,10 @@ TEST_XML(xpath_paths_abbrev_w3c_17, "<node><para/><para type='warning'/><para ty
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para[@type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(n, "para[@type=\"warning\"]") % 4 % 6 % 11 % 13 % 15;
|
||||
CHECK_XPATH_NODESET(c, STR("para[@type=\"warning\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("para[@type=\"warning\"]")) % 4 % 6 % 11 % 13 % 15;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_18, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='error'/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -199,10 +199,10 @@ TEST_XML(xpath_paths_abbrev_w3c_18, "<node><para/><para type='warning'/><para ty
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para[@type=\"warning\"][5]");
|
||||
CHECK_XPATH_NODESET(n, "para[@type=\"warning\"][5]") % 15;
|
||||
CHECK_XPATH_NODESET(c, STR("para[@type=\"warning\"][5]"));
|
||||
CHECK_XPATH_NODESET(n, STR("para[@type=\"warning\"][5]")) % 15;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_19a, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='error'/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -210,10 +210,10 @@ TEST_XML(xpath_paths_abbrev_w3c_19a, "<node><para/><para type='warning'/><para t
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para[5][@type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(n, "para[5][@type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(c, STR("para[5][@type=\"warning\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("para[5][@type=\"warning\"]"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_19b, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -221,10 +221,10 @@ TEST_XML(xpath_paths_abbrev_w3c_19b, "<node><para/><para type='warning'/><para t
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "para[5][@type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(n, "para[5][@type=\"warning\"]") % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("para[5][@type=\"warning\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("para[5][@type=\"warning\"]")) % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_20, "<node><chapter><title>foo</title></chapter><chapter><title>Introduction</title></chapter><chapter><title>introduction</title></chapter><chapter/><chapter><title>Introduction</title><title>foo</title></chapter></node>")
|
||||
|
@ -232,10 +232,10 @@ TEST_XML(xpath_paths_abbrev_w3c_20, "<node><chapter><title>foo</title></chapter>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "chapter[title=\"Introduction\"]");
|
||||
CHECK_XPATH_NODESET(n, "chapter[title=\"Introduction\"]") % 6 % 13;
|
||||
CHECK_XPATH_NODESET(c, STR("chapter[title=\"Introduction\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("chapter[title=\"Introduction\"]")) % 6 % 13;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_21, "<node><chapter><title>foo</title></chapter><chapter><title>Introduction</title></chapter><chapter><title>introduction</title></chapter><chapter/><chapter><title>Introduction</title><title>foo</title></chapter></node>")
|
||||
|
@ -243,10 +243,10 @@ TEST_XML(xpath_paths_abbrev_w3c_21, "<node><chapter><title>foo</title></chapter>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "chapter[title]");
|
||||
CHECK_XPATH_NODESET(n, "chapter[title]") % 3 % 6 % 9 % 13;
|
||||
CHECK_XPATH_NODESET(c, STR("chapter[title]"));
|
||||
CHECK_XPATH_NODESET(n, STR("chapter[title]")) % 3 % 6 % 9 % 13;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_abbrev_w3c_22, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/></node>")
|
||||
|
@ -254,10 +254,10 @@ TEST_XML(xpath_paths_abbrev_w3c_22, "<node><employee/><employee secretary=''/><e
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "employee[@secretary and @assistant]");
|
||||
CHECK_XPATH_NODESET(n, "employee[@secretary and @assistant]") % 8 % 11;
|
||||
CHECK_XPATH_NODESET(c, STR("employee[@secretary and @assistant]"));
|
||||
CHECK_XPATH_NODESET(n, STR("employee[@secretary and @assistant]")) % 8 % 11;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,10 +7,10 @@ TEST_XML(xpath_paths_w3c_1, "<node><para/><foo/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para");
|
||||
CHECK_XPATH_NODESET(n, "child::para") % 3 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para")) % 3 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_2, "<node><para/><foo/><para/></node>")
|
||||
|
@ -18,10 +18,10 @@ TEST_XML(xpath_paths_w3c_2, "<node><para/><foo/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::*");
|
||||
CHECK_XPATH_NODESET(n, "child::*") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("child::*"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::*")) % 3 % 4 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_3, "<node>pcdata<child/><![CDATA[cdata]]></node>")
|
||||
|
@ -29,10 +29,10 @@ TEST_XML(xpath_paths_w3c_3, "<node>pcdata<child/><![CDATA[cdata]]></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::text()");
|
||||
CHECK_XPATH_NODESET(n, "child::text()") % 3 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("child::text()"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::text()")) % 3 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_4, "<node>pcdata<child/><![CDATA[cdata]]></node>")
|
||||
|
@ -40,10 +40,10 @@ TEST_XML(xpath_paths_w3c_4, "<node>pcdata<child/><![CDATA[cdata]]></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::node()");
|
||||
CHECK_XPATH_NODESET(n, "child::node()") % 3 % 4 % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("child::node()"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::node()")) % 3 % 4 % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_5, "<node name='value' foo='bar' />")
|
||||
|
@ -51,10 +51,10 @@ TEST_XML(xpath_paths_w3c_5, "<node name='value' foo='bar' />")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "attribute::name");
|
||||
CHECK_XPATH_NODESET(n, "attribute::name") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("attribute::name"));
|
||||
CHECK_XPATH_NODESET(n, STR("attribute::name")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_6, "<node name='value' foo='bar' />")
|
||||
|
@ -62,10 +62,10 @@ TEST_XML(xpath_paths_w3c_6, "<node name='value' foo='bar' />")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "attribute::*");
|
||||
CHECK_XPATH_NODESET(n, "attribute::*") % 3 % 4;
|
||||
CHECK_XPATH_NODESET(c, STR("attribute::*"));
|
||||
CHECK_XPATH_NODESET(n, STR("attribute::*")) % 3 % 4;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_7, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -73,11 +73,11 @@ TEST_XML(xpath_paths_w3c_7, "<node><para><para/><para/><foo><para/></foo></para>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "descendant::para");
|
||||
CHECK_XPATH_NODESET(n, "descendant::para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("para"), "descendant::para") % 4 % 5 % 7;
|
||||
CHECK_XPATH_NODESET(c, STR("descendant::para"));
|
||||
CHECK_XPATH_NODESET(n, STR("descendant::para")) % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR("descendant::para")) % 4 % 5 % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_8, "<node><div><font><div><div/></div></font></div></node>")
|
||||
|
@ -85,10 +85,10 @@ TEST_XML(xpath_paths_w3c_8, "<node><div><font><div><div/></div></font></div></no
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "ancestor::div");
|
||||
CHECK_XPATH_NODESET(n.child("div").child("font").child("div").child("div"), "ancestor::div") % 5 % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("ancestor::div"));
|
||||
CHECK_XPATH_NODESET(n.child(STR("div")).child(STR("font")).child(STR("div")).child(STR("div")), STR("ancestor::div")) % 5 % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_9, "<node><div><font><div><div/></div></font></div></node>")
|
||||
|
@ -96,10 +96,10 @@ TEST_XML(xpath_paths_w3c_9, "<node><div><font><div><div/></div></font></div></no
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "ancestor-or-self::div");
|
||||
CHECK_XPATH_NODESET(n.child("div").child("font").child("div").child("div"), "ancestor-or-self::div") % 6 % 5 % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("ancestor-or-self::div"));
|
||||
CHECK_XPATH_NODESET(n.child(STR("div")).child(STR("font")).child(STR("div")).child(STR("div")), STR("ancestor-or-self::div")) % 6 % 5 % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_10, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -107,11 +107,11 @@ TEST_XML(xpath_paths_w3c_10, "<node><para><para/><para/><foo><para/></foo></para
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "descendant-or-self::para");
|
||||
CHECK_XPATH_NODESET(n, "descendant-or-self::para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("para"), "descendant-or-self::para") % 3 % 4 % 5 % 7;
|
||||
CHECK_XPATH_NODESET(c, STR("descendant-or-self::para"));
|
||||
CHECK_XPATH_NODESET(n, STR("descendant-or-self::para")) % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR("descendant-or-self::para")) % 3 % 4 % 5 % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_11, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -119,11 +119,11 @@ TEST_XML(xpath_paths_w3c_11, "<node><para><para/><para/><foo><para/></foo></para
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "self::para");
|
||||
CHECK_XPATH_NODESET(n, "self::para");
|
||||
CHECK_XPATH_NODESET(n.child("para"), "self::para") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("self::para"));
|
||||
CHECK_XPATH_NODESET(n, STR("self::para"));
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR("self::para")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_12, "<chapter><para><para/><para/><foo><para/></foo></para><foo/><para/></chapter>")
|
||||
|
@ -132,8 +132,8 @@ TEST_XML(xpath_paths_w3c_12, "<chapter><para><para/><para/><foo><para/></foo></p
|
|||
|
||||
xml_node c;
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::chapter/descendant::para");
|
||||
CHECK_XPATH_NODESET(doc, "child::chapter/descendant::para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("child::chapter/descendant::para"));
|
||||
CHECK_XPATH_NODESET(doc, STR("child::chapter/descendant::para")) % 3 % 4 % 5 % 7 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_13, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -142,8 +142,8 @@ TEST_XML(xpath_paths_w3c_13, "<node><para><para/><para/><foo><para/></foo></para
|
|||
|
||||
xml_node c;
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::*/child::para");
|
||||
CHECK_XPATH_NODESET(doc, "child::*/child::para") % 3 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("child::*/child::para"));
|
||||
CHECK_XPATH_NODESET(doc, STR("child::*/child::para")) % 3 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_14, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -151,13 +151,13 @@ TEST_XML(xpath_paths_w3c_14, "<node><para><para/><para/><foo><para/></foo></para
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/");
|
||||
CHECK_XPATH_NODESET(c, STR("/"));
|
||||
|
||||
CHECK_XPATH_NODESET(doc, "/") % 1;
|
||||
CHECK_XPATH_NODESET(n, "/") % 1;
|
||||
CHECK_XPATH_NODESET(n.child("para"), "/") % 1;
|
||||
CHECK_XPATH_NODESET(doc, STR("/")) % 1;
|
||||
CHECK_XPATH_NODESET(n, STR("/")) % 1;
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR("/")) % 1;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_15, "<node><para><para/><para/><foo><para/></foo></para><foo/><para/></node>")
|
||||
|
@ -165,11 +165,11 @@ TEST_XML(xpath_paths_w3c_15, "<node><para><para/><para/><foo><para/></foo></para
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/descendant::para");
|
||||
CHECK_XPATH_NODESET(n, "/descendant::para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("para"), "/descendant::para") % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("/descendant::para"));
|
||||
CHECK_XPATH_NODESET(n, STR("/descendant::para")) % 3 % 4 % 5 % 7 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("para")), STR("/descendant::para")) % 3 % 4 % 5 % 7 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_16, "<node><olist><item/></olist><item/><olist><olist><item/><item/></olist></olist></node>")
|
||||
|
@ -177,11 +177,11 @@ TEST_XML(xpath_paths_w3c_16, "<node><olist><item/></olist><item/><olist><olist><
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/descendant::olist/child::item");
|
||||
CHECK_XPATH_NODESET(n, "/descendant::olist/child::item") % 4 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(n.child("olist"), "/descendant::olist/child::item") % 4 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("/descendant::olist/child::item"));
|
||||
CHECK_XPATH_NODESET(n, STR("/descendant::olist/child::item")) % 4 % 8 % 9;
|
||||
CHECK_XPATH_NODESET(n.child(STR("olist")), STR("/descendant::olist/child::item")) % 4 % 8 % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_17, "<node><para/><para/><para/><para/></node>")
|
||||
|
@ -189,10 +189,10 @@ TEST_XML(xpath_paths_w3c_17, "<node><para/><para/><para/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[position()=1]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[position()=1]") % 3;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[position()=1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[position()=1]")) % 3;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_18, "<node><para/><para/><para/><para/></node>")
|
||||
|
@ -200,10 +200,10 @@ TEST_XML(xpath_paths_w3c_18, "<node><para/><para/><para/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[position()=last()]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[position()=last()]") % 6;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[position()=last()]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[position()=last()]")) % 6;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_19, "<node><para/><para/><para/><para/></node>")
|
||||
|
@ -211,10 +211,10 @@ TEST_XML(xpath_paths_w3c_19, "<node><para/><para/><para/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[position()=last()-1]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[position()=last()-1]") % 5;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[position()=last()-1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[position()=last()-1]")) % 5;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_20, "<node><para/><para/><para/><para/></node>")
|
||||
|
@ -222,10 +222,10 @@ TEST_XML(xpath_paths_w3c_20, "<node><para/><para/><para/><para/></node>")
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[position()>1]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[position()>1]") % 4 % 5 % 6;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[position()>1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[position()>1]")) % 4 % 5 % 6;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_21, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
|
||||
|
@ -233,10 +233,10 @@ TEST_XML(xpath_paths_w3c_21, "<node><chapter/><chapter/><chapter/><chapter/><cha
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
|
||||
xml_node n = doc.child(STR("node")).child(STR("chapter")).next_sibling().next_sibling();
|
||||
|
||||
CHECK_XPATH_NODESET(c, "following-sibling::chapter[position()=1]");
|
||||
CHECK_XPATH_NODESET(n, "following-sibling::chapter[position()=1]") % 6;
|
||||
CHECK_XPATH_NODESET(c, STR("following-sibling::chapter[position()=1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[position()=1]")) % 6;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_22, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
|
||||
|
@ -244,10 +244,10 @@ TEST_XML(xpath_paths_w3c_22, "<node><chapter/><chapter/><chapter/><chapter/><cha
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
|
||||
xml_node n = doc.child(STR("node")).child(STR("chapter")).next_sibling().next_sibling();
|
||||
|
||||
CHECK_XPATH_NODESET(c, "preceding-sibling::chapter[position()=1]");
|
||||
CHECK_XPATH_NODESET(n, "preceding-sibling::chapter[position()=1]") % 4;
|
||||
CHECK_XPATH_NODESET(c, STR("preceding-sibling::chapter[position()=1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("preceding-sibling::chapter[position()=1]")) % 4;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_23, "<node><figure><figure/><figure/><foo><figure/></foo></figure><foo/><figure/></node>")
|
||||
|
@ -255,11 +255,11 @@ TEST_XML(xpath_paths_w3c_23, "<node><figure><figure/><figure/><foo><figure/></fo
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/descendant::figure[position()=4]");
|
||||
CHECK_XPATH_NODESET(n, "/descendant::figure[position()=4]") % 7;
|
||||
CHECK_XPATH_NODESET(n.child("figure"), "/descendant::figure[position()=4]") % 7;
|
||||
CHECK_XPATH_NODESET(c, STR("/descendant::figure[position()=4]"));
|
||||
CHECK_XPATH_NODESET(n, STR("/descendant::figure[position()=4]")) % 7;
|
||||
CHECK_XPATH_NODESET(n.child(STR("figure")), STR("/descendant::figure[position()=4]")) % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_24, "<doc><chapter/><chapter/><chapter/><chapter/><chapter><section/><section/><section/></chapter><chapter/></doc>")
|
||||
|
@ -267,11 +267,11 @@ TEST_XML(xpath_paths_w3c_24, "<doc><chapter/><chapter/><chapter/><chapter/><chap
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("doc").child("chapter");
|
||||
xml_node n = doc.child(STR("doc")).child(STR("chapter"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "/child::doc/child::chapter[position()=5]/child::section[position()=2]");
|
||||
CHECK_XPATH_NODESET(n, "/child::doc/child::chapter[position()=5]/child::section[position()=2]") % 9;
|
||||
CHECK_XPATH_NODESET(doc, "/child::doc/child::chapter[position()=5]/child::section[position()=2]") % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("/child::doc/child::chapter[position()=5]/child::section[position()=2]"));
|
||||
CHECK_XPATH_NODESET(n, STR("/child::doc/child::chapter[position()=5]/child::section[position()=2]")) % 9;
|
||||
CHECK_XPATH_NODESET(doc, STR("/child::doc/child::chapter[position()=5]/child::section[position()=2]")) % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_25, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='error'/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -279,10 +279,10 @@ TEST_XML(xpath_paths_w3c_25, "<node><para/><para type='warning'/><para type='war
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[attribute::type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[attribute::type=\"warning\"]") % 4 % 6 % 11 % 13 % 15;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[attribute::type=\"warning\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[attribute::type=\"warning\"]")) % 4 % 6 % 11 % 13 % 15;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_26, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='error'/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -290,10 +290,10 @@ TEST_XML(xpath_paths_w3c_26, "<node><para/><para type='warning'/><para type='war
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[attribute::type=\"warning\"][position()=5]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[attribute::type=\"warning\"][position()=5]") % 15;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[attribute::type=\"warning\"][position()=5]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[attribute::type=\"warning\"][position()=5]")) % 15;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_27a, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='error'/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -301,10 +301,10 @@ TEST_XML(xpath_paths_w3c_27a, "<node><para/><para type='warning'/><para type='wa
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[position()=5][attribute::type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[position()=5][attribute::type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[position()=5][attribute::type=\"warning\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[position()=5][attribute::type=\"warning\"]"));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_27b, "<node><para/><para type='warning'/><para type='warning'/><para/><para type='warning'/><para type='warning'/><para type='warning'/></node>")
|
||||
|
@ -312,10 +312,10 @@ TEST_XML(xpath_paths_w3c_27b, "<node><para/><para type='warning'/><para type='wa
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::para[position()=5][attribute::type=\"warning\"]");
|
||||
CHECK_XPATH_NODESET(n, "child::para[position()=5][attribute::type=\"warning\"]") % 9;
|
||||
CHECK_XPATH_NODESET(c, STR("child::para[position()=5][attribute::type=\"warning\"]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::para[position()=5][attribute::type=\"warning\"]")) % 9;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_28, "<node><chapter><title>foo</title></chapter><chapter><title>Introduction</title></chapter><chapter><title>introduction</title></chapter><chapter/><chapter><title>Introduction</title><title>foo</title></chapter></node>")
|
||||
|
@ -323,10 +323,10 @@ TEST_XML(xpath_paths_w3c_28, "<node><chapter><title>foo</title></chapter><chapte
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::chapter[child::title='Introduction']");
|
||||
CHECK_XPATH_NODESET(n, "child::chapter[child::title='Introduction']") % 6 % 13;
|
||||
CHECK_XPATH_NODESET(c, STR("child::chapter[child::title='Introduction']"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::chapter[child::title='Introduction']")) % 6 % 13;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_29, "<node><chapter><title>foo</title></chapter><chapter><title>Introduction</title></chapter><chapter><title>introduction</title></chapter><chapter/><chapter><title>Introduction</title><title>foo</title></chapter></node>")
|
||||
|
@ -334,10 +334,10 @@ TEST_XML(xpath_paths_w3c_29, "<node><chapter><title>foo</title></chapter><chapte
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::chapter[child::title]");
|
||||
CHECK_XPATH_NODESET(n, "child::chapter[child::title]") % 3 % 6 % 9 % 13;
|
||||
CHECK_XPATH_NODESET(c, STR("child::chapter[child::title]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::chapter[child::title]")) % 3 % 6 % 9 % 13;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_30, "<node><abstract/><chapter/><chapter/><references/><appendix/></node>")
|
||||
|
@ -345,10 +345,10 @@ TEST_XML(xpath_paths_w3c_30, "<node><abstract/><chapter/><chapter/><references/>
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::*[self::chapter or self::appendix]");
|
||||
CHECK_XPATH_NODESET(n, "child::*[self::chapter or self::appendix]") % 4 % 5 % 7;
|
||||
CHECK_XPATH_NODESET(c, STR("child::*[self::chapter or self::appendix]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::*[self::chapter or self::appendix]")) % 4 % 5 % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_31a, "<node><abstract/><chapter/><chapter/><references/><appendix/></node>")
|
||||
|
@ -356,10 +356,10 @@ TEST_XML(xpath_paths_w3c_31a, "<node><abstract/><chapter/><chapter/><references/
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::*[self::chapter or self::appendix][position()=last()]");
|
||||
CHECK_XPATH_NODESET(n, "child::*[self::chapter or self::appendix][position()=last()]") % 7;
|
||||
CHECK_XPATH_NODESET(c, STR("child::*[self::chapter or self::appendix][position()=last()]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::*[self::chapter or self::appendix][position()=last()]")) % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_w3c_31b, "<node><abstract/><chapter/><chapter/><references/><appendix/><chapter/></node>")
|
||||
|
@ -367,10 +367,10 @@ TEST_XML(xpath_paths_w3c_31b, "<node><abstract/><chapter/><chapter/><references/
|
|||
doc.precompute_document_order();
|
||||
|
||||
xml_node c;
|
||||
xml_node n = doc.child("node");
|
||||
xml_node n = doc.child(STR("node"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, "child::*[self::chapter or self::appendix][position()=last()]");
|
||||
CHECK_XPATH_NODESET(n, "child::*[self::chapter or self::appendix][position()=last()]") % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("child::*[self::chapter or self::appendix][position()=last()]"));
|
||||
CHECK_XPATH_NODESET(n, STR("child::*[self::chapter or self::appendix][position()=last()]")) % 8;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
77
tests/writer_string.cpp
Normal file
77
tests/writer_string.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "writer_string.hpp"
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
static bool test_narrow(const std::string& result, const char* expected, size_t length)
|
||||
{
|
||||
// check result
|
||||
if (result != std::string(expected, expected + length)) return false;
|
||||
|
||||
// check comparison operator (incorrect implementation can theoretically early-out on zero terminators...)
|
||||
if (length > 0 && result == std::string(expected, expected + length - 1) + "?") return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void xml_writer_string::write(const void* data, size_t size)
|
||||
{
|
||||
contents += std::string(static_cast<const char*>(data), size);
|
||||
}
|
||||
|
||||
std::string xml_writer_string::as_narrow() const
|
||||
{
|
||||
return contents;
|
||||
}
|
||||
|
||||
std::wstring xml_writer_string::as_wide() const
|
||||
{
|
||||
CHECK(contents.size() % sizeof(wchar_t) == 0);
|
||||
|
||||
return std::wstring(reinterpret_cast<const wchar_t*>(contents.data()), contents.size() / sizeof(wchar_t));
|
||||
}
|
||||
|
||||
std::basic_string<pugi::char_t> xml_writer_string::as_string() const
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE // to avoid "condition is always true" warning in BCC
|
||||
CHECK(contents.size() % sizeof(pugi::char_t) == 0);
|
||||
#endif
|
||||
|
||||
return std::basic_string<pugi::char_t>(reinterpret_cast<const pugi::char_t*>(contents.data()), contents.size() / sizeof(pugi::char_t));
|
||||
}
|
||||
|
||||
std::string save_narrow(const pugi::xml_document& doc, unsigned int flags, pugi::encoding_t encoding)
|
||||
{
|
||||
xml_writer_string writer;
|
||||
|
||||
doc.save(writer, STR(""), flags, encoding);
|
||||
|
||||
return writer.as_narrow();
|
||||
}
|
||||
|
||||
bool test_save_narrow(const pugi::xml_document& doc, unsigned int flags, pugi::encoding_t encoding, const char* expected, size_t length)
|
||||
{
|
||||
return test_narrow(save_narrow(doc, flags, encoding), expected, length);
|
||||
}
|
||||
|
||||
std::string write_narrow(pugi::xml_node node, unsigned int flags, pugi::encoding_t encoding)
|
||||
{
|
||||
xml_writer_string writer;
|
||||
|
||||
node.print(writer, STR(""), flags, encoding);
|
||||
|
||||
return writer.as_narrow();
|
||||
}
|
||||
|
||||
bool test_write_narrow(pugi::xml_node node, unsigned int flags, pugi::encoding_t encoding, const char* expected, size_t length)
|
||||
{
|
||||
return test_narrow(write_narrow(node, flags, encoding), expected, length);
|
||||
}
|
||||
|
||||
std::wstring write_wide(pugi::xml_node node, unsigned int flags, pugi::encoding_t encoding)
|
||||
{
|
||||
xml_writer_string writer;
|
||||
|
||||
node.print(writer, STR(""), flags, encoding);
|
||||
|
||||
return writer.as_wide();
|
||||
}
|
27
tests/writer_string.hpp
Normal file
27
tests/writer_string.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef HEADER_WRITER_STRING_HPP
|
||||
#define HEADER_WRITER_STRING_HPP
|
||||
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct xml_writer_string: public pugi::xml_writer
|
||||
{
|
||||
std::string contents;
|
||||
|
||||
virtual void write(const void* data, size_t size);
|
||||
|
||||
std::string as_narrow() const;
|
||||
std::wstring as_wide() const;
|
||||
std::basic_string<pugi::char_t> as_string() const;
|
||||
};
|
||||
|
||||
std::string save_narrow(const pugi::xml_document& doc, unsigned int flags, pugi::encoding_t encoding);
|
||||
bool test_save_narrow(const pugi::xml_document& doc, unsigned int flags, pugi::encoding_t encoding, const char* expected, size_t length);
|
||||
|
||||
std::string write_narrow(pugi::xml_node node, unsigned int flags, pugi::encoding_t encoding);
|
||||
bool test_write_narrow(pugi::xml_node node, unsigned int flags, pugi::encoding_t encoding, const char* expected, size_t length);
|
||||
|
||||
std::wstring write_wide(pugi::xml_node node, unsigned int flags, pugi::encoding_t encoding);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue