blob: f39d26935163978844f8ed4cb74450b0038567d6 [file] [log] [blame]
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<document>
<properties>
<title>XML Configurations</title>
</properties>
<body>
<section name="XML Configurations">
<p>
An important sub category of hierarchical configurations files are XML
documents. <em>Commons Configuration</em> ships with the
<code><a href="../apidocs/org/apache/commons/configuration2/XMLConfiguration.html">
XMLConfiguration</a></code> class that can read and write files of this
type. All features described in the chapter about
<a href="howto_hierarchical.html">Hierarchical Configurations</a> are
supported by XML configurations as well. In this chapter the additional
functionality offered by the <code>XMLConfiguration</code> class is
discussed.
</p>
<subsection name="Validation of XML configuration files">
<p>
XML parsers provide support for validation of XML documents to ensure that they
conform to a certain DTD or XML Schema. This feature can be useful for
configuration files, too. <code>XMLConfiguration</code> allows this feature
to be enabled when files are loaded.
</p>
<strong>Validation using a DTD</strong>
<p>
The easiest way to turn on validation is to simply set the
<code>validating</code> property to <strong>true</strong> in the
initialization parameters of the configuration builder as shown in
the following example:
</p>
<source><![CDATA[
Parameters params = new Parameters();
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(params.xml()
.setFileName("myconfig.xml")
.setValidating(true));
// This will throw a ConfigurationException if the XML document does not
// conform to its DTD.
XMLConfiguration config = builder.getConfiguration();
]]></source>
<p>
Setting the <code>validating</code> flag to <strong>true</strong> will cause
<code>XMLConfiguration</code> to use a validating XML parser. At this parser
a custom <code>ErrorHandler</code> will be registered, which throws
exceptions on simple and fatal parsing errors.
</p>
<strong>Validation using a Schema</strong>
<p>
XML Parsers also provide support for validating XML documents using an
XML Schema. <code>XMLConfiguration</code> provides a simple mechanism for enabling
this by setting the <code>schemaValidation</code> flag to <strong>true</strong>. This
will also set the <code>validating</code> flag to <strong>true</strong> so both do not
need to be set. The XML Parser will then use the schema defined in the
XML document to validate it. Enabling schema validation will also
enable the parser's namespace support.
</p>
<p>
<source><![CDATA[
Parameters params = new Parameters();
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(params.xml()
.setFileName("myconfig.xml")
.setSchemaValidation(true));
// This will throw a ConfigurationException if the XML document does not
// conform to its Schema.
XMLConfiguration config = builder.getConfiguration();
]]></source>
</p>
</subsection>
<subsection name="Default Entity Resolution">
<p>
There is also some support for dealing with DTD files. Often the
DTD of an XML document is stored locally so that it can be quickly
accessed. However the <code>DOCTYPE</code> declaration of the document
points to a location on the web as in the following example:
</p>
<source><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
]]></source>
<p>
When working with XML documents directly you would use an
<code>EntityResolver</code> in such a case. The task of such an
entity resolver is to point the XML parser to the location of the
file referred to by the declaration. So in our example the entity
resolver would load the DTD file from a local cache instead of
retrieving it from the internet.
</p>
<p>
<code>XMLConfiguration</code> provides a simple default implementation of
an <code>EntityResolver</code> in form of the
<code><a href="../apidocs/org/apache/commons/configuration2/resolver/DefaultEntityResolver.html">
DefaultEntityResolver</a></code> class. This implementation is initialized
by calling the <code>registerEntityId()</code> method with the
public IDs of the entities to be retrieved and their corresponding
local URLs. Then the instance is passed to the configuration builder's
initialization parameters. As an example, consider that the DTD file for
our example document is stored on the class path. We can register it
at <code>XMLConfiguration</code> using the following code:
</p>
<source><![CDATA[
Parameters params = new Parameters();
DefaultEntityResolver resolver = new DefaultEntityResolver();
// load the URL to the DTD file from class path
URL dtdURL = getClass().getResource("web-app_2.2.dtd");
// register it at the resolver
resolver.registerEntityId("-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
dtdURL);
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(params.xml()
.setFileName("web.xml")
.setEntityResolver(resolver)
.setValidating(true));
XMLConfiguration config = builder.getConfiguration();
]]></source>
<p>
This basically tells the XML configuration to use the specified
URL when it encounters the given public ID.
</p>
</subsection>
<subsection name="Enhanced Entity Resolution">
<p>
While the default entity resolver can be used under certain circumstances,
it does not work well when using combined configurations from
multiple sources. Furthermore, in many circumstances the programmatic nature of
registering entities will tie the application tightly to the
XML content. In addition, because it only works with the public id it
cannot support XML documents using an XML Schema.
</p>
<p>
<a href="http://xml.apache.org/commons/components/resolver/resolver-article.html#s.whats.wrong">XML
Entity and URI Resolvers</a> describes using a set of catalog files to
resolve entities. <em>Commons Configuration</em> provides support for
this Catalog Resolver through its own
<code><a href="../apidocs/org/apache/commons/configuration2/resolver/CatalogResolver.html">
CatalogResolver</a></code> class.
</p>
<source><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<Employees xmlns="https://commons.apache.org/employee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://commons.apache.org/employee https://commons.apache.org/sample.xsd">
<Employee>
<SSN>555121211</SSN>
<Name>John Doe</Name>
<DateOfBirth>1975-05-15</DateOfBirth>
<EmployeeType>Exempt</EmployeeType>
<Salary>100000</Salary>
</Employee>
</Employees>]]></source>
<p>
The XML sample above is an XML document using a default namespace of
https://commons.apache.org/employee. The schemaLocation allows a set
of namespaces and hints to the location of their corresponding
schemas. When processing the document the parser will pass the hint,
in this case https://commons.apache.org/sample.xsd, to the entity resolver
as the system id. More information on using schema locations can be found
at <a href="http://www.w3.org/TR/xmlschema-0/#schemaLocation">schemaLocation</a>.
</p>
<p>
The example that follows shows how to use the <code>CatalogResolver</code> class when
creating an <code>XMLConfiguration</code>. It should be noted that by using the
<code>setEntityResolver()</code> method any EntityResolver may be used, not just those
provided by <em>Commons Configuration</em>.
</p>
<source><![CDATA[
Parameters params = new Parameters();
CatalogResolver resolver = new CatalogResolver();
resolver.setCatalogFiles("local/catalog.xml","http://test.org/catalogs/catalog1.xml");
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(params.xml()
.setFileName("config.xml")
.setEntityResolver(resolver)
.setSchemaValidation(true)); // enable schema validation
XMLConfiguration config = builder.getConfiguration();
]]></source>
</subsection>
<subsection name="Extending Validation and Entity Resolution">
<p>
The mechanisms provided with <em>Commons Configuration</em> will hopefully be
sufficient in most cases; however, there will certainly be circumstances
where they are not. <code>XMLConfiguration</code> provides two extension mechanisms
that should provide applications with all the flexibility they may
need. The first, registering a custom Entity Resolver has already been
discussed in the preceding section. The second is that <code>XMLConfiguration</code>
provides a generic way of setting up the XML parser to use: A preconfigured
<code>DocumentBuilder</code> object can be passed to the
initialization parameters of the configuration builder.
</p>
<p>
So an application can create a <code>DocumentBuilder</code> object
and initialize it according to its special needs. Then this
object must be passed to the configuration builder when it is initialized. When loading
a configuration file, the passed in <code>DocumentBuilder</code> will
be used instead of the default one. <em>Note:</em> If a custom
<code>DocumentBuilder</code> is used, the mechanisms for entity
resolution described in the previous sub sections are disabled. The
following example shows how a custom <code>DocumentBuilder</code>
can be set:
</p>
<source><![CDATA[
Parameters params = new Parameters();
DocumentBuilder docBuilder = ... // set up a custom document builder
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(params.xml()
.setFileName("config.xml")
.setDocumentBuilder(docBuilder);
XMLConfiguration config = builder.getConfiguration();
]]></source>
</subsection>
<subsection name="Builder Configuration Related to XML Configurations">
<p>
XML configurations are created in the typical way: via configuration
builders. The initialization parameters supported for them include all
the settings available for hierarchical configurations and file-based
configurations. In addition, the
<code><a href="../apidocs/org/apache/commons/configuration2/builder/XMLBuilderProperties.html">
XMLBuilderProperties</a></code> interface defines settings specific to
XML configurations. This includes
<ul>
<li>a custom <code>DocumentBuilder</code></li>
<li>a custom <code>EntityResolver</code></li>
<li>flags whether the XML document is to be validated and how this
validation is to be performed</li>
<li>the public and the system ID of the document when it is written</li>
</ul>
</p>
<p>
A parameters object for an XML configuration can be obtained using
the <code>xml()</code> method of a
<code><a href="../apidocs/org/apache/commons/configuration2/builder/fluent/Parameter.html">
Parameters</a></code> instance. It returns an object implementing the
<code><a href="../apidocs/org/apache/commons/configuration2/builder/fluent/XMLBuilderParameters.html">
XMLBuilderParameters</a></code> interface which defines set
methods for all the available properties.
</p>
</subsection>
</section>
</body>
</document>