/**\r
* Extension of AbstractXMLObject that implements a DOMCachingXMLObject.\r
*/\r
- class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject, public virtual DOMCachingXMLObject\r
+ class XMLTOOL_API AbstractDOMCachingXMLObject : public AbstractXMLObject, public DOMCachingXMLObject\r
{\r
public:\r
virtual ~AbstractDOMCachingXMLObject();\r
*/\r
XMLObject* prepareForAssignment(const XMLObject* oldValue, XMLObject* newValue);\r
\r
- AbstractDOMCachingXMLObject() : m_dom(NULL), m_document(NULL) {}\r
-\r
/**\r
* Constructor\r
* \r
* @param namespaceURI the namespace the element is in\r
* @param elementLocalName the local name of the XML element this Object represents\r
*/\r
- AbstractDOMCachingXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix)\r
+ AbstractDOMCachingXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
: AbstractXMLObject(namespaceURI,elementLocalName, namespacePrefix), m_dom(NULL), m_document(NULL) {}\r
\r
private:\r
}\r
\r
protected:\r
- AbstractXMLObject() : m_typeQname(NULL), m_parent(NULL) {}\r
-\r
/**\r
* Constructor\r
* \r
* @param namespaceURI the namespace the element is in\r
* @param elementLocalName the local name of the XML element this Object represents\r
*/\r
- AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix)\r
+ AbstractXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
: m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL) {\r
addNamespace(Namespace(namespaceURI, namespacePrefix));\r
}\r
const XMLCh* uri=ns.getNamespaceURI();\r
\r
// Check to see if the prefix is already declared properly above this node.\r
- if (!ns.alwaysDeclare() && domElement->getParentNode() &&\r
- XMLString::equals(domElement->getParentNode()->lookupNamespaceURI(prefix),uri))\r
- return;\r
+ if (!ns.alwaysDeclare()) {\r
+ const XMLCh* declared=lookupNamespaceURI(domElement->getParentNode(),prefix);\r
+ if (declared && XMLString::equals(declared,uri))\r
+ return;\r
+ }\r
\r
if (prefix && *prefix) {\r
XMLCh* xmlns=new XMLCh[XMLString::stringLen(XMLConstants::XMLNS_PREFIX) + XMLString::stringLen(prefix) + 2*sizeof(XMLCh)];\r
domElement->setAttributeNS(XMLConstants::XMLNS_NS, XMLConstants::XMLNS_PREFIX, uri);\r
}\r
}\r
+\r
+ const XMLCh* lookupNamespaceURI(const DOMNode* n, const XMLCh* prefix) const {\r
+ // Return NULL if no declaration in effect. The empty string signifies the null namespace.\r
+ if (!n || n->getNodeType()!=DOMNode::ELEMENT_NODE)\r
+ return NULL; // we're done\r
+ DOMNamedNodeMap* attributes = static_cast<const DOMElement*>(n)->getAttributes();\r
+ if (!attributes)\r
+ return lookupNamespaceURI(n->getParentNode(),prefix); // defer to parent\r
+ DOMNode* childNode;\r
+ DOMAttr* attribute;\r
+ for (XMLSize_t i=0; i<attributes->getLength(); i++) {\r
+ childNode = attributes->item(i);\r
+ if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) // not an attribute?\r
+ continue;\r
+ attribute = static_cast<DOMAttr*>(childNode);\r
+ if (!XMLString::equals(attribute->getNamespaceURI(),XMLConstants::XMLNS_NS))\r
+ continue; // not a namespace declaration\r
+ // Local name should be the prefix and the value would be the URI, except for the default namespace.\r
+ if (!prefix && XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX))\r
+ return attribute->getNodeValue();\r
+ else if (XMLString::equals(prefix,attribute->getLocalName()))\r
+ return attribute->getNodeValue();\r
+ }\r
+ // Defer to parent.\r
+ return lookupNamespaceURI(n->getParentNode(),prefix);\r
+ }\r
};\r
\r
void AbstractXMLObjectMarshaller::marshallNamespaces(const XMLObject& xmlObject, DOMElement* domElement) const\r
\r
const XMLCh* nsuri=attribute->getNamespaceURI();\r
if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) {\r
- XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");\r
- xmlObject.addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));\r
- continue;\r
+ if (XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX)) {\r
+ XT_log.debug("found default namespace declaration, adding it to the list of namespaces on the XMLObject");\r
+ xmlObject.addNamespace(Namespace(attribute->getValue(), NULL, true));\r
+ continue;\r
+ }\r
+ else {\r
+ XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");\r
+ xmlObject.addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));\r
+ continue;\r
+ }\r
}\r
else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) {\r
XT_log.debug("found xsi:type declaration, setting the schema type of the XMLObject");\r
public:\r
UnmarshallingTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME) {}\r
\r
- void setUp() {
- XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());
- Marshaller::registerMarshaller(m_qname, new SimpleXMLObjectMarshaller());
- Unmarshaller::registerUnmarshaller(m_qname, new SimpleXMLObjectUnmarshaller());
- }
-
- void tearDown() {
- XMLObjectBuilder::deregisterBuilder(m_qname);
- Marshaller::deregisterMarshaller(m_qname);
- Unmarshaller::deregisterUnmarshaller(m_qname);
- }
+ void setUp() {\r
+ XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
+ Marshaller::registerMarshaller(m_qname, new SimpleXMLObjectMarshaller());\r
+ Unmarshaller::registerUnmarshaller(m_qname, new SimpleXMLObjectUnmarshaller());\r
+ }\r
+\r
+ void tearDown() {\r
+ XMLObjectBuilder::deregisterBuilder(m_qname);\r
+ Marshaller::deregisterMarshaller(m_qname);\r
+ Unmarshaller::deregisterUnmarshaller(m_qname);\r
+ }\r
\r
void testUnmarshallingWithAttributes() {\r
- ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithAttribute.xml");\r
+ TS_TRACE("testUnmarshallingWithAttributes");\r
+\r
+ string path=data_path + "SimpleXMLObjectWithAttribute.xml";\r
+ ifstream fs(path.c_str());\r
DOMDocument* doc=nonvalidatingPool->parse(fs);\r
TS_ASSERT(doc!=NULL);\r
\r
auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
TS_ASSERT(sxObject.get()!=NULL);\r
\r
- auto_ptr_XMLCh expectedId("Firefly");\r
- TSM_ASSERT_SAME_DATA("ID was not expected value", expectedId.get(), sxObject->getId(), XMLString::stringLen(expectedId.get()));\r
+ auto_ptr_XMLCh expected("Firefly");\r
+ TSM_ASSERT_SAME_DATA("ID was not expected value", expected.get(), sxObject->getId(), XMLString::stringLen(expected.get()));\r
+ }\r
+\r
+ void testUnmarshallingWithElementContent() {\r
+ TS_TRACE("testUnmarshallingWithElementContent");\r
+\r
+ string path=data_path + "SimpleXMLObjectWithContent.xml";\r
+ ifstream fs(path.c_str());\r
+ DOMDocument* doc=nonvalidatingPool->parse(fs);\r
+ TS_ASSERT(doc!=NULL);\r
+\r
+ const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
+ TS_ASSERT(u!=NULL);\r
+\r
+ auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ TS_ASSERT(sxObject.get()!=NULL);\r
+\r
+ auto_ptr_XMLCh expected("Sample Content");\r
+ TSM_ASSERT_SAME_DATA("Element content was not expected value", expected.get(), sxObject->getValue(), XMLString::stringLen(expected.get()));\r
+ }\r
+\r
+ void testUnmarshallingWithChildElements() {\r
+ TS_TRACE("testUnmarshallingWithChildElements");\r
+\r
+ string path=data_path + "SimpleXMLObjectWithChildren.xml";\r
+ ifstream fs(path.c_str());\r
+ DOMDocument* doc=nonvalidatingPool->parse(fs);\r
+ TS_ASSERT(doc!=NULL);\r
+\r
+ const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
+ TS_ASSERT(u!=NULL);\r
+\r
+ auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ TS_ASSERT(sxObject.get()!=NULL);\r
+\r
+ TSM_ASSERT_EQUALS("Number of child elements was not expected value", 2, sxObject->getSimpleXMLObjects().size());\r
+ }\r
+\r
+ void testUnmarshallingWithUnknownChild() {\r
+ TS_TRACE("testUnmarshallingWithUnknownChild");\r
+\r
+ string path=data_path + "SimpleXMLObjectWithUnknownChild.xml";\r
+ ifstream fs(path.c_str());\r
+ DOMDocument* doc=nonvalidatingPool->parse(fs);\r
+ TS_ASSERT(doc!=NULL);\r
+\r
+ const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
+ TS_ASSERT(u!=NULL);\r
+\r
+ TS_ASSERT_THROWS(u->unmarshall(doc->getDocumentElement(),true),UnmarshallingException);\r
+ doc->release();\r
}\r
};\r
\r
extern ParserPool* validatingPool;\r
extern ParserPool* nonvalidatingPool;\r
+extern string data_path;\r
\r
#if defined (_MSC_VER)\r
#pragma warning( push )\r
if (XMLString::equals(attribute->getLocalName(),SimpleXMLObject::ID_ATTRIB_NAME)) {\r
simpleXMLObject.setId(attribute->getValue());\r
}\r
+ else {\r
+ throw UnmarshallingException("Unknown attribute cannot be processed by parent object.");\r
+ }\r
}\r
\r
void processElementContent(XMLObject& xmlObject, const XMLCh* elementContent) const {\r
\r
ParserPool* validatingPool=NULL;\r
ParserPool* nonvalidatingPool=NULL;\r
+std::string data_path = "../xmltoolingtest/data/";\r
\r
class ToolingFixture : public CxxTest::GlobalFixture\r
{\r
return false;\r
validatingPool = new ParserPool(true,true);\r
nonvalidatingPool = new ParserPool();\r
+ if (getenv("XMLTOOLINGTEST_DATA"))\r
+ data_path=std::string(getenv("XMLTOOLINGTEST_DATA")) + "/";\r
return true;\r
}\r
bool tearDownWorld() {\r
{\r
public:\r
void testCatalog(void) {\r
- auto_ptr_XMLCh temp("../xmltoolingtest/data/catalog.xml");\r
+ std::string path=data_path + "catalog.xml";\r
+ auto_ptr_XMLCh temp(path.c_str());\r
TS_ASSERT(validatingPool->loadCatalog(temp.get()));\r
}\r
};\r
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
>\r
<File\r
+ RelativePath=".\MarshallingTest.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\UnknownTest.cpp"\r
>\r
</File>\r
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
>\r
<File\r
+ RelativePath=".\MarshallingTest.h"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputName)".cpp "$(InputPath)""\r
+ Outputs=""$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputName)".cpp "$(InputPath)""\r
+ Outputs=""$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
RelativePath=".\UnknownTest.h"\r
>\r
<FileConfiguration\r