From 412a7f2204e6dd6dc0c7e11822e99f95b58f5178 Mon Sep 17 00:00:00 2001 From: jez Date: Mon, 23 Feb 2009 09:14:35 +0000 Subject: [PATCH] initial version of parseQName --- include/XML/QName.hpp | 42 ++++++++++++++++++++++++++++++++++++++ tests/Utils/test_qname.hpp | 19 +++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/XML/QName.hpp b/include/XML/QName.hpp index c7026410..4ed7aa5c 100644 --- a/include/XML/QName.hpp +++ b/include/XML/QName.hpp @@ -3,6 +3,7 @@ #include #include +#include template > class QualifiedName @@ -10,6 +11,47 @@ class QualifiedName typedef string_adaptor SA; public: + /** + *

This function processes a raw XML 1.0 name in the current + * context by removing the prefix and looking it up among the + * prefixes currently declared. + * + *

If the raw name has a prefix that has not been declared, + * then the return value will be empty.

+ * + *

Note that attribute names are processed differently than + * element names: an unprefixed element name will received the + * default Namespace (if any), while an unprefixed element name + * will not.

+ */ + template + static QualifiedName parseQName(const string_type& rawname, + bool is_attribute, + const UriMapper& mapper) + { + static string_type COLON = SA::construct_from_utf8(":"); + + typename string_adaptor::size_type index = string_adaptor::find(rawname, COLON); + + if(index == string_adaptor::npos()) + return QualifiedName(SA::empty_string(), + rawname, + is_attribute ? SA::empty_string() : mapper(SA::empty_string())); + + // prefix + string_type prefix = string_adaptor::substr(rawname, 0, index); + string_type localName = string_adaptor::substr(rawname, index + 1); + + if((string_adaptor::length(prefix) == 0) || + (string_adaptor::length(localName) == 0) || + (string_adaptor::find(localName, COLON) != string_adaptor::npos())) + throw std::runtime_error("Bad qname : " + SA::asStdString(rawname)); + + string_type uri = mapper(prefix); + + return QualifiedName(prefix, localName, uri); + } // parseQName + QualifiedName(const string_type& localName) : prefix_(), localName_(localName), diff --git a/tests/Utils/test_qname.hpp b/tests/Utils/test_qname.hpp index 8344c393..9cfe9f40 100644 --- a/tests/Utils/test_qname.hpp +++ b/tests/Utils/test_qname.hpp @@ -10,6 +10,7 @@ class QualifiedNameTest : public TestCase { typedef string_adaptor SA; typedef QualifiedName QN; + typedef QualifiedNameTest QNT; public: QualifiedNameTest(const std::string& name) : TestCase(name) @@ -104,6 +105,23 @@ public: assertTrue(q.has_prefix()); assertTrue(SA::construct_from_utf8("t") == q.prefix()); } // testPrefix + + static string_type uri_mapper(const string_type& prefix) + { + return SA::construct_from_utf8("http://test/"); + } // uri_mapper + + void testParseBadQName() + { + try { + QN::parseQName(SA::construct_from_utf8("::::"), false, QNT::uri_mapper); + assertFalse("oops - should have thrown here"); + } + catch(std::runtime_error&) { + // yay + } + } // testParseBadQName + }; // class QualifiedNameTest template @@ -122,6 +140,7 @@ TestSuite* QualifiedNameTest_suite() suiteOfTests->addTest(new TestCaller("testAssignment", &QNT::testAssignment)); suiteOfTests->addTest(new TestCaller("testClarkName", &QNT::testClarkName)); suiteOfTests->addTest(new TestCaller("testPrefix", &QNT::testPrefix)); + suiteOfTests->addTest(new TestCaller("testParseBadQName", &QNT::testParseBadQName)); return suiteOfTests; } // QualifiedNameTest_suite