using namespace xmltooling;\r
using namespace std;\r
\r
+set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;\r
+\r
AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()\r
{\r
for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)\r
AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)\r
: AbstractXMLObject(src)\r
{\r
+ m_idAttribute = m_attributeMap.end();\r
for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {\r
m_attributeMap[i->first] = XMLString::replicate(i->second);\r
}\r
+ if (src.m_idAttribute != src.m_attributeMap.end()) {\r
+ m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);\r
+ }\r
}\r
\r
-void AbstractAttributeExtensibleXMLObject::setAttribute(QName& qualifiedName, const XMLCh* value)\r
+void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)\r
{\r
map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);\r
if (i!=m_attributeMap.end()) {\r
i->second=XMLString::replicate(value);\r
}\r
else {\r
+ if (m_idAttribute==i)\r
+ m_idAttribute=m_attributeMap.end();\r
m_attributeMap.erase(i);\r
}\r
+ \r
+ if (ID) {\r
+ m_idAttribute=i;\r
+ }\r
}\r
else if (value) {\r
releaseThisandParentDOM();\r
m_attributeMap[qualifiedName]=XMLString::replicate(value);\r
+ if (ID) {\r
+ m_idAttribute = m_attributeMap.find(qualifiedName);\r
+ } \r
}\r
}\r
* AbstractXMLObject mixin that implements AttributeExtensibleXMLObject.\r
* Inherit from this class to add support for attribute wildcarding.\r
*/\r
- class XMLTOOL_API AbstractAttributeExtensibleXMLObject : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject\r
+ class XMLTOOL_API AbstractAttributeExtensibleXMLObject\r
+ : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject\r
{\r
public:\r
virtual ~AbstractAttributeExtensibleXMLObject();\r
\r
- virtual const XMLCh* getAttribute(QName& qualifiedName) const {\r
+ const XMLCh* getAttribute(const QName& qualifiedName) const {\r
std::map<QName,XMLCh*>::const_iterator i=m_attributeMap.find(qualifiedName);\r
return (i==m_attributeMap.end()) ? NULL : i->second;\r
}\r
\r
- virtual void setAttribute(QName& qualifiedName, const XMLCh* value);\r
+ void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false);\r
+ \r
+ const std::map<QName,XMLCh*>& getExtensionAttributes() const {\r
+ return m_attributeMap;\r
+ }\r
+ \r
+ const XMLCh* getXMLID() const {\r
+ return (m_idAttribute == m_attributeMap.end()) ? NULL : m_idAttribute->second;\r
+ }\r
\r
protected:\r
- AbstractAttributeExtensibleXMLObject() {}\r
+ AbstractAttributeExtensibleXMLObject() {\r
+ m_idAttribute = m_attributeMap.end();\r
+ }\r
\r
/** Copy constructor. */\r
AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src);\r
\r
/** Map of arbitrary attributes. */\r
std::map<QName,XMLCh*> m_attributeMap;\r
+ \r
+ /** Points to the last attribute designated as an XML ID. */\r
+ std::map<QName,XMLCh*>::const_iterator m_idAttribute;\r
};\r
\r
};\r
const QName* getSchemaType() const {\r
return m_typeQname;\r
}\r
+ \r
+ const XMLCh* getXMLID() const {\r
+ return NULL;\r
+ }\r
\r
bool hasParent() const {\r
return m_parent != NULL;\r
\r
using namespace xercesc;\r
\r
+#if defined (_MSC_VER)\r
+ #pragma warning( push )\r
+ #pragma warning( disable : 4250 4251 )\r
+#endif\r
+\r
namespace xmltooling {\r
\r
/**\r
*/\r
class XMLTOOL_API AttributeExtensibleXMLObject : public virtual XMLObject\r
{\r
- public:\r
+ protected:\r
AttributeExtensibleXMLObject() {}\r
+ \r
+ public:\r
virtual ~AttributeExtensibleXMLObject() {}\r
\r
/**\r
- * Gets the value of an XML attribute of the object\r
+ * Gets the value of an XML attribute of the object.\r
* \r
* @param qualifiedName qualified name of the attribute \r
* @return the attribute value, or NULL\r
*/\r
- virtual const XMLCh* getAttribute(QName& qualifiedName) const=0;\r
+ virtual const XMLCh* getAttribute(const QName& qualifiedName) const=0;\r
\r
/**\r
- * Sets (or clears) an XML attribute of the object \r
+ * Sets (or clears) an XML attribute of the object.\r
* \r
* @param qualifiedName qualified name of the attribute \r
* @param value value to set, or NULL to clear\r
+ * @param ID true iff the attribute is an XML ID\r
*/\r
- virtual void setAttribute(QName& qualifiedName, const XMLCh* value)=0;\r
+ virtual void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false)=0;\r
+\r
+ /**\r
+ * Gets an immutable map of the extended XML attributes of the object.\r
+ * \r
+ * This set is not guaranteed to (and generally will not) include\r
+ * attributes defined directly on the object's "type".\r
+ */\r
+ virtual const std::map<QName,XMLCh*>& getExtensionAttributes() const=0;\r
+ \r
+ /**\r
+ * Gets an immutable list of all the ID attributes currently registered.\r
+ * \r
+ * @return list of all the ID attributes currently registered\r
+ */\r
+ static const std::set<QName>& getRegisteredIDAttributes() {\r
+ return m_idAttributeSet;\r
+ }\r
+ \r
+ /**\r
+ * Registers a new attribute as being of XML ID type.\r
+ * \r
+ * @param name the qualified attribute name\r
+ */\r
+ static void registerIDAttribute(const QName& name) {\r
+ m_idAttributeSet.insert(name);\r
+ }\r
+\r
+ /**\r
+ * Deregisters an ID attribute.\r
+ * \r
+ * @param name the qualified attribute name\r
+ */\r
+ static void deregisterIDAttribute(const QName& name) {\r
+ m_idAttributeSet.erase(name);\r
+ }\r
+ \r
+ /**\r
+ * Deregisters all ID attributes.\r
+ */\r
+ static void deregisterIDAttributes() {\r
+ m_idAttributeSet.clear();\r
+ }\r
+\r
+ private:\r
+ /** Set of attributes to treat as XML IDs. */\r
+ static std::set<QName> m_idAttributeSet;\r
};\r
\r
};\r
\r
+#if defined (_MSC_VER)\r
+ #pragma warning( pop )\r
+#endif\r
+\r
#endif /* __xmltooling_attrextxmlobj_h__ */\r
virtual const QName* getSchemaType() const=0;\r
\r
/**\r
+ * Gets the value of the ID attribute set on this object, if any.\r
+ * \r
+ * @return an ID value or NULL \r
+ */\r
+ virtual const XMLCh* getXMLID() const=0;\r
+ \r
+ /**\r
* Checks to see if this object has a parent.\r
* \r
* @return true if the object has a parent, false if not\r
registerCredentialResolvers();
registerTrustEngines();
#endif
+
+ // Register xml:id as an ID attribute.
+ static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d);
+ AttributeExtensibleXMLObject::registerIDAttribute(QName(XMLConstants::XML_NS, xmlid));
}
catch (const xercesc::XMLException&) {
log.fatal("caught exception while initializing Xerces");
KeyInfoSchemaValidators.destroyValidators();
EncryptionSchemaValidators.destroyValidators();
XMLToolingException::deregisterFactories();
+ AttributeExtensibleXMLObject::deregisterIDAttributes();
#ifndef XMLTOOLING_NO_XMLSEC
TrustEngineManager.deregisterFactories();
IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
/**
+ * Implements get/set methods and a private member for a string XML attribute,
+ * plus a getXMLID override.
+ *
+ * @param proper the proper name of the attribute
+ */
+#define IMPL_ID_ATTRIB(proper) \
+ IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
+ const XMLCh* getXMLID() const { \
+ return m_##proper; \
+ }
+
+/**
* Implements get/set methods and a private member for a DateTime XML attribute.
*
* @param proper the proper name of the attribute
}
IMPL_XMLOBJECT_CLONE(KeyInfo);
- IMPL_STRING_ATTRIB(Id);
+ IMPL_ID_ATTRIB(Id);
IMPL_TYPED_CHILDREN(KeyName,m_children.end());
IMPL_TYPED_CHILDREN(KeyValue,m_children.end());
IMPL_TYPED_CHILDREN(RetrievalMethod,m_children.end());
return new SimpleXMLObject(*this);
}
+ const XMLCh* getXMLID() const { return getId(); }
const XMLCh* getId() const { return m_id; }
void setId(const XMLCh* id) { m_id=prepareForAssignment(m_id,id); }