XInclude is a very simple “import” facility for XML
documents. With the XInclude directive, you can easily include one XML
document in another either as XML or as plain (and escaped) text. This
means that you can break down your documents into as many files as you see
fit and reference the pieces in a simple, standard way. We should note
that it is also possible to do this in another way, using XML entity
declarations, but they are fraught with problems. XInclude is simpler and
does what its name implies, including the specified document at the
current location; you just have to declare the proper namespace for the
new <include> element.
Here is an example:
<Bookxmlns:xi="http://www.w3.org/2001/XInclude"><Title>LearningJava</Title><xi:includehref="chapter1.xml"/><xi:includehref="chapter2.xml"/><xi:includehref="chapter3.xml"/>...</Book>
We’ve used the namespace identifier xi to qualify the <include> elements that we use to import
the chapters of our book. By default, the file is imported as XML content,
which means that the parser incorporates the included document as part of
our document. The resulting DOM or SAX view will show the merged documents
as one. Alternatively, we can use the parse attribute to
specify that we want the target included as text only. In this case, the
text is automatically escaped for us like a CDATA section. For example, we
could use it to include an XML example in our book without danger of it
being intepreted as part of our file:
<Example><Title>TheZooInventoryExample</Title><xi:includeparse="text"href="zooinventory.xml"/></Example>
Here, the entire zooinventory.xml file will be included as nicely escaped text for us (not added to our document as XML).
XInclude also allows for “fallback” content to be specified using a
nested fallback element. The
fallback element may point to another
file or simply hold XML to be used if the included file can’t be found.
For example:
<xi:includeparse="text "href="zooinventory.xml"><xi:fallbackhref="filenotfound.xml"/></xi:include><xi:includeparse="text"href="example.xml"><xi:fallback>Thisexampleismissing...</xi:fallback></xi:include>
In the first case, if zooinventory.xml is not
found, the filenotfound.xml file will be included. In
the second case, the “missing” text will be included instead of the file.
If there is no fallback specified, a parse-time fatal error occurs. An
empty fallback element can be used to
suppress any error. Fallbacks may also be nested within fallbacks to
combine these behaviors.
Getting XInclude to work for us requires simply turning on a
couple of flags before we begin parsing our file. First, because the
XInclude facility uses namespaces, we have to turn on namespace
processing in our parser factory. Second, we have to explicitly tell the
parser to interpret the include directives. To modify our PrintDOM example to perform the includes before printing the
result, we turn these flags on the factory before creating a DocumentBuilder instance:
DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();// enable XInclude processingfactory.setNamespaceAware(true);factory.setXIncludeAware(true);DocumentBuilderparser=factory.newDocumentBuilder();Documentdocument=parser.parse(input);
Both of those options should really be the defaults these days. But they have historically come later to XML and so been treated as special features that have to be enabled. We should also mention before we move on that XInclude can make use of XPath expressions (via an API called XPointer) in order to include just selected parts of an XML document.