From 53521055a35f5ac5f0d8d0720cd84907c2c58a63 Mon Sep 17 00:00:00 2001 From: cantor Date: Sat, 21 Aug 2010 03:33:15 +0000 Subject: [PATCH 1/1] https://bugs.internet2.edu/jira/browse/CPPOST-41 git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/branches/REL_1@771 de75baf8-a10c-0410-a50a-987c0e22f00f --- xmltooling/AbstractXMLObject.cpp | 39 ++++++++++++++++----------- xmltooling/io/AbstractXMLObjectMarshaller.cpp | 8 ++++++ xmltooling/io/AbstractXMLObjectMarshaller.h | 6 +++++ xmltooling/util/XMLHelper.cpp | 21 ++++++++++++--- xmltooling/util/XMLHelper.h | 7 ++--- 5 files changed, 58 insertions(+), 23 deletions(-) diff --git a/xmltooling/AbstractXMLObject.cpp b/xmltooling/AbstractXMLObject.cpp index 10d5844..b7c3cac 100644 --- a/xmltooling/AbstractXMLObject.cpp +++ b/xmltooling/AbstractXMLObject.cpp @@ -130,24 +130,31 @@ void XMLObject::setNil(const XMLCh* value) void AbstractXMLObject::addNamespace(const Namespace& ns) const { - std::set::iterator i = m_namespaces.find(ns); - if (i == m_namespaces.end()) - m_namespaces.insert(ns); - else { - if (ns.alwaysDeclare()) - const_cast(*i).setAlwaysDeclare(true); - switch (ns.usage()) { - case Namespace::Indeterminate: - break; - case Namespace::VisiblyUsed: - const_cast(*i).setUsage(Namespace::VisiblyUsed); - break; - case Namespace::NonVisiblyUsed: - if (i->usage() == Namespace::Indeterminate) - const_cast(*i).setUsage(Namespace::NonVisiblyUsed); - break; + for (set::const_iterator n = m_namespaces.begin(); n != m_namespaces.end(); ++n) { + // Look for the prefix in the existing set. + if (XMLString::equals(ns.getNamespacePrefix(), n->getNamespacePrefix())) { + // See if it's the same declaration, and overlay various properties if so. + if (XMLString::equals(ns.getNamespaceURI(), n->getNamespaceURI())) { + if (ns.alwaysDeclare()) + const_cast(*n).setAlwaysDeclare(true); + switch (ns.usage()) { + case Namespace::Indeterminate: + break; + case Namespace::VisiblyUsed: + const_cast(*n).setUsage(Namespace::VisiblyUsed); + break; + case Namespace::NonVisiblyUsed: + if (n->usage() == Namespace::Indeterminate) + const_cast(*n).setUsage(Namespace::NonVisiblyUsed); + break; + } + } + return; } } + + // If the prefix is now, go ahead and add it. + m_namespaces.insert(ns); } void AbstractXMLObject::removeNamespace(const Namespace& ns) diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.cpp b/xmltooling/io/AbstractXMLObjectMarshaller.cpp index c28bcbf..d3af0cb 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.cpp +++ b/xmltooling/io/AbstractXMLObjectMarshaller.cpp @@ -96,6 +96,8 @@ DOMElement* AbstractXMLObjectMarshaller::marshall( } // If we get here, we didn't have a usable DOM (and/or we released the one we had). + prepareForMarshalling(); + // We may need to create our own document. bool bindDocument=false; if (!document) { @@ -161,6 +163,8 @@ DOMElement* AbstractXMLObjectMarshaller::marshall( } // If we get here, we didn't have a usable DOM (and/or we released the one we had). + prepareForMarshalling(); + m_log.debug("creating root element to marshall"); DOMElement* domElement = parentElement->getOwnerDocument()->createElementNS( getElementQName().getNamespaceURI(), getElementQName().getLocalPart() @@ -382,3 +386,7 @@ void AbstractXMLObjectMarshaller::marshallContent( void AbstractXMLObjectMarshaller::marshallAttributes(DOMElement* domElement) const { } + +void AbstractXMLObjectMarshaller::prepareForMarshalling() const +{ +} diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.h b/xmltooling/io/AbstractXMLObjectMarshaller.h index 16eb776..c22b173 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.h +++ b/xmltooling/io/AbstractXMLObjectMarshaller.h @@ -141,6 +141,12 @@ namespace xmltooling { * @throws MarshallingException thrown if there is a problem marshalling an attribute */ virtual void marshallAttributes(xercesc::DOMElement* domElement) const; + + /** + * Called before marshalling in the event that a new DOM is being generated. + *

Allows objects to adjust internal state prior to the marshalling step. + */ + virtual void prepareForMarshalling() const; }; }; diff --git a/xmltooling/util/XMLHelper.cpp b/xmltooling/util/XMLHelper.cpp index 34d82f6..7bc43ba 100644 --- a/xmltooling/util/XMLHelper.cpp +++ b/xmltooling/util/XMLHelper.cpp @@ -119,9 +119,9 @@ XMLObject* XMLHelper::getXMLObjectById(XMLObject& tree, const XMLCh* id) return nullptr; } -void XMLHelper::getNonVisiblyUsedPrefixes(const XMLObject& tree, set& prefixes) +void XMLHelper::getNonVisiblyUsedPrefixes(const XMLObject& tree, map& prefixes) { - set child_prefixes; + map child_prefixes; const list& children = tree.getOrderedChildren(); for (list::const_iterator i = children.begin(); i != children.end(); ++i) { if (*i) @@ -136,13 +136,26 @@ void XMLHelper::getNonVisiblyUsedPrefixes(const XMLObject& tree, set& p case Namespace::Indeterminate: break; case Namespace::VisiblyUsed: - child_prefixes.erase(ns->getNamespacePrefix() ? ns->getNamespacePrefix() : &chNull); + { + // See if the prefix was noted as non-visible below. + const XMLCh* p = ns->getNamespacePrefix() ? ns->getNamespacePrefix() : &chNull; + map::iterator decl = child_prefixes.find(p); + if (decl != child_prefixes.end()) { + // It's declared below, see if it's the same namespace. If so, pull it from the set, + // otherwise leave it in the set. + if (decl->second == (ns->getNamespaceURI() ? ns->getNamespaceURI() : &chNull)) + child_prefixes.erase(decl); + } break; + } case Namespace::NonVisiblyUsed: - prefixes.insert(ns->getNamespacePrefix() ? ns->getNamespacePrefix() : &chNull); + // It may already be in the map from another branch of the tree, but as long + // as it's set to something so the parent knows about it, we're good. + prefixes[ns->getNamespacePrefix() ? ns->getNamespacePrefix() : &chNull] = (ns->getNamespaceURI() ? ns->getNamespaceURI() : &chNull); break; } } + prefixes.insert(child_prefixes.begin(), child_prefixes.end()); } diff --git a/xmltooling/util/XMLHelper.h b/xmltooling/util/XMLHelper.h index 7198823..ade134c 100644 --- a/xmltooling/util/XMLHelper.h +++ b/xmltooling/util/XMLHelper.h @@ -135,12 +135,13 @@ namespace xmltooling { static XMLObject* getXMLObjectById(XMLObject& tree, const XMLCh* id); /** - * Returns a list of non-visibly-used namespace prefixes found in a tree. + * Returns the set of non-visibly-used namespace declarations found in a tree. + *

Each member of the set is a prefix/URI pair. * * @param tree root of tree to search - * @param prefixes container to store prefix list + * @param prefixes container to store declarations */ - static void getNonVisiblyUsedPrefixes(const XMLObject& tree, std::set& prefixes); + static void getNonVisiblyUsedPrefixes(const XMLObject& tree, std::map& prefixes); /** * Gets the QName for the given DOM node. -- 2.1.4