Creating SAML Objects from an XML Source

Creating SAML objects from an XML source is done through a process known as unmarshalling which operates on DOM Elements. The OpenSAML 2 library contains unmarshalling support for known types and elements within its implementation classes, and the appropriate one is selected based off of either the XML Schema type of the Element to be unmarshalled or the Element's QName (a tuple representing the namespace the element is in and the element's name).

Unmarshalling is part of the core XMLObject interface. As a result, you can unmarshall either against a constructed (but empty) XMLObject, or using XMLObjectBuilder methods that take DOM elements or DOM documents. The document can be bound during this process as well, to control which XMLObject instance is responsible for freeing the document.

Unmarshalling Basics

  1. (Optionally) Parse your XML file using ParserPool::parse() to construct a DOM representation of the document. Both schema-aware (validating) or non-validating parser pools can be used. The SAMLConfig class includes methods for accessing both kinds of pools. The pool API improves efficiency by reusing parser instances for you.
  2. Get a builder using the XMLObjectBuilder::getBuilder(const DOMElement*) method. The element argument is the root element from which you wish to begin unmarshalling. This is normally the document element if you're unmarshalling data from a file.
  3. Invoke the buildFromElement(DOMElement*) or buildFromDocument(DOMDocument*) method on the returned XMLObjectBuilder . Alternatively, just build an empty object and use its unmarshall() methods directly. Usually the builder methods are easier to use.

By default, building from a DOMDocument will bind the document to the root object returned, and document ownership is transferred to the object. You must free the resulting XMLObject, but the document will be freed automatically when the bound object is. Building from an element does not bind the owning document by default, but this can be overridden.

Unmarshalling Example

The following example shows the parsing and unmarshalling of a SAML 2 metadata document. Exception handling code has been omitted here for readability, but the example does show how to protect the application from leaks by wrapping the DOMDocument in a janitor class before unmarshalling. If that results in an error, the document will be freed for you. Otherwise, the documentis released from the janitor after unmarshalling succeeds.

	// Parse metadata file
	string inCommonMDFile = "/data/org/opensaml/saml2/metadata/InCommon-metadata.xml";
	ifstream in(inCommonMDFile);
	DOMDocument* inCommonMDDoc = XMLToolingConfig::getConfig()->getParser().parse(in);
	XercesJanitor<DOMDocument> janitor(inCommonMDDoc);

	// Get apropriate builder.
	const XMLObjectBuilder* builder=XMLObjectBuilder::getBuilder(inCommonMDDoc->getDocumentElement());

	// Unmarshall using the document, an EntitiesDescriptor in this case.
	XMLObject* xo=builder->buildFromDocument(inCommonMDDoc);
	janitor.release();
	EntitiesDescriptor* inCommonMD = dynamic_cast<EntitiesDescriptor*>(xo);

After all that, only inCommonMD (or xo) needs to be deleted when you're done with it. If an exception is thrown, nothing will leak.

Additional Unmarshalling Information