added is_qname function, and tests

This commit is contained in:
jez 2008-08-01 13:02:41 +01:00
parent e0fcea7d71
commit f14cb010a3
3 changed files with 150 additions and 20 deletions

View file

@ -30,3 +30,4 @@ vs9\*.user
lib
arabica-2008-july
arabica-2008-july.*
vs9/mangle.sln

View file

@ -4,35 +4,66 @@
#include <XML/XMLCharacterClasses.hpp>
#include <text/UnicodeCharacters.hpp>
// QName
//[7] QName ::= PrefixedName | UnprefixedName
//[8] PrefixedName ::= Prefix ':' LocalPart
//[9] UnprefixedName ::= LocalPart
//[10] Prefix ::= NCName
//[11] LocalPart ::= NCName
// NCName
// [4] NCName ::= NCNameStartChar NCNameChar* //An XML Name, minus the ":"
// [5] NCNameChar ::= NameChar - ':'
// [6] NCNameStartChar ::= Letter | '_' } // namespace XML
namespace Arabica
{
namespace XML
{
bool is_ncname(const std::string::const_iterator& b,
const std::string::const_iterator& e);
bool is_ncname(const std::string& str)
inline bool is_ncname(const std::string& str)
{
return is_ncname(str.begin(), str.end());
} // is_ncname
inline bool is_ncname(const std::string::const_iterator& b,
const std::string::const_iterator& e)
{
using namespace Arabica::text;
std::string::const_iterator s = str.begin();
if(b == e)
return false; // zero length
std::string::const_iterator s = b;
if(!(is_letter(*s) || (*s == Unicode<char>::LOW_LINE)))
return false;
++s;
for(std::string::const_iterator se = str.end(); s != se; ++s)
for( ; s != e; ++s)
{
wchar_t c = static_cast<wchar_t>(*s);
if(!(is_letter(c) ||
is_digit(c) ||
(c == Unicode<wchar_t>::FULL_STOP) ||
(c == Unicode<wchar_t>::HYPHEN_MINUS) ||
(c == Unicode<wchar_t>::LOW_LINE) ||
is_combining_char(c) ||
is_extender(c)))
if(!is_ncname_char(c))
return false;
}
return true;
} // is_ncname
inline bool is_qname(const std::string& str)
{
using namespace Arabica::text;
size_t colon_index = str.find(Unicode<char>::COLON);
if(colon_index == std::string::npos)
return is_ncname(str);
std::string::const_iterator b = str.begin();
return is_ncname(b, b+colon_index) &&
is_ncname(b+(colon_index+1), str.end());
} // is_qname
} // namespace XML
} // namespace Arabica

View file

@ -5,13 +5,13 @@
using namespace Arabica::XML;
class XMLStringTest : public TestCase
class NCNameTest : public TestCase
{
public:
XMLStringTest(std::string name) :
NCNameTest(std::string name) :
TestCase(name)
{
} // XMLStringTest
} // NCNameTest
void test1()
{
@ -42,19 +42,117 @@ public:
{
assertFalse(is_ncname("xsl:foo"));
} // test6
}; // class NCNameTest
}; // class XMLStringTest
TestSuite* NCNameTest_suite()
{
TestSuite* suiteOfTests = new TestSuite();
suiteOfTests->addTest(new TestCaller<NCNameTest>("test1", &NCNameTest::test1));
suiteOfTests->addTest(new TestCaller<NCNameTest>("test2", &NCNameTest::test2));
suiteOfTests->addTest(new TestCaller<NCNameTest>("test3", &NCNameTest::test3));
suiteOfTests->addTest(new TestCaller<NCNameTest>("test4", &NCNameTest::test4));
suiteOfTests->addTest(new TestCaller<NCNameTest>("test5", &NCNameTest::test5));
suiteOfTests->addTest(new TestCaller<NCNameTest>("test6", &NCNameTest::test6));
return suiteOfTests;
} // NCNameTest_suite
class QNameTest : public TestCase
{
public:
QNameTest(std::string name) :
TestCase(name)
{
} // QNameTest
void test1()
{
assertTrue(is_qname("woo"));
} // test1
void test2()
{
assertTrue(is_qname("WOO"));
} // test2
void test3()
{
assertFalse(is_qname("???"));
} // test3
void test4()
{
assertTrue(is_qname("a_b"));
} // test4
void test5()
{
assertTrue(is_qname("a:b"));
} // test5
void test6()
{
assertTrue(is_qname("xsl:foo"));
} // test6
void test7()
{
assertFalse(is_qname(":foo"));
} // test7
void test8()
{
assertFalse(is_qname("foo:"));
} // test7
void test9()
{
assertFalse(is_qname("xsl::foo"));
} // test7
void test10()
{
assertFalse(is_qname("xsl:foo:"));
} // test7
void test11()
{
assertFalse(is_qname("$rr"));
} // test11
void test12()
{
assertFalse(is_qname("root/child"));
} // test12
}; // class QNameTest
TestSuite* QNameTest_suite()
{
TestSuite* suiteOfTests = new TestSuite();
suiteOfTests->addTest(new TestCaller<QNameTest>("test1", &QNameTest::test1));
suiteOfTests->addTest(new TestCaller<QNameTest>("test2", &QNameTest::test2));
suiteOfTests->addTest(new TestCaller<QNameTest>("test3", &QNameTest::test3));
suiteOfTests->addTest(new TestCaller<QNameTest>("test4", &QNameTest::test4));
suiteOfTests->addTest(new TestCaller<QNameTest>("test5", &QNameTest::test5));
suiteOfTests->addTest(new TestCaller<QNameTest>("test6", &QNameTest::test6));
suiteOfTests->addTest(new TestCaller<QNameTest>("test7", &QNameTest::test7));
suiteOfTests->addTest(new TestCaller<QNameTest>("test8", &QNameTest::test8));
suiteOfTests->addTest(new TestCaller<QNameTest>("test9", &QNameTest::test9));
suiteOfTests->addTest(new TestCaller<QNameTest>("test10", &QNameTest::test10));
suiteOfTests->addTest(new TestCaller<QNameTest>("test11", &QNameTest::test11));
suiteOfTests->addTest(new TestCaller<QNameTest>("test12", &QNameTest::test12));
return suiteOfTests;
} // QNameTest_suite
TestSuite* XMLStringTest_suite()
{
TestSuite* suiteOfTests = new TestSuite();
suiteOfTests->addTest(new TestCaller<XMLStringTest>("test1", &XMLStringTest::test1));
suiteOfTests->addTest(new TestCaller<XMLStringTest>("test2", &XMLStringTest::test2));
suiteOfTests->addTest(new TestCaller<XMLStringTest>("test3", &XMLStringTest::test3));
suiteOfTests->addTest(new TestCaller<XMLStringTest>("test4", &XMLStringTest::test4));
suiteOfTests->addTest(new TestCaller<XMLStringTest>("test5", &XMLStringTest::test5));
suiteOfTests->addTest(new TestCaller<XMLStringTest>("test6", &XMLStringTest::test6));
suiteOfTests->addTest(NCNameTest_suite());
suiteOfTests->addTest(QNameTest_suite());
return suiteOfTests;
} // XMLStringTest_suite