You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2004/12/23 19:43:00 UTC
cvs commit: jakarta-commons/configuration/xdocs howto_xml.xml
oheger 2004/12/23 10:43:00
Modified: configuration/xdocs howto_xml.xml
Log:
Updated howtos for XML configurations
Revision Changes Path
1.7 +166 -43 jakarta-commons/configuration/xdocs/howto_xml.xml
Index: howto_xml.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/configuration/xdocs/howto_xml.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- howto_xml.xml 22 Oct 2004 01:40:48 -0000 1.6
+++ howto_xml.xml 23 Dec 2004 18:43:00 -0000 1.7
@@ -10,15 +10,15 @@
<body>
<section name="Using XML based Configurations">
<p>
- This section explains how to use Hierarchical
- and Structured XML datasets.
+ This section explains how to use hierarchical
+ and structured XML datasets.
</p>
</section>
<section name="Hierarchical properties">
<p>
- The XML document we used in the section about composite configuration was quite simple. Because of its
+ The XML document we used in the section about ConfigurationFactory was quite simple. Because of its
tree-like nature XML documents can represent data that is
structured in many ways. This section explains how to deal with
such structured documents.
@@ -156,38 +156,13 @@
which table?
</p>
<p>
- The answer is, with our actual approach we have no chance to
- obtain this knowledge! If XML documents are loaded this way,
- their exact structure is lost. Though all field names are found
- and stored the information which field belongs to which table
- is not saved. Fortunately Configuration provides a way of
- dealing with structured XML documents. To enable this feature
- the configuration definition file has to be slightly altered.
- It becomes:
- </p>
- <source><![CDATA[
-<?xml version="1.0" encoding="ISO-8859-1" ?>
-
-<configuration>
- <properties fileName="usergui.properties"/>
- <xml fileName="gui.xml"/>
- <hierarchicalXml fileName="tables.xml"/>
-</configuration>
-]]></source>
- <p>
- Note that one <code>xml</code> element was replaced by a
- <code>hierarchicalXml</code> element. This element tells the configuration
- factory that not the default class for processing XML documents
- should be used, but the class <code>HierarchicalXMLConfiguration</code>.
- As the name implies this class is capable of saving the
- hierarchy of XML documents thus keeping their structure.
- </p>
- <p>
- When working with such hierarchical properties configuration keys
- used to query properties support an extended syntax. All components
+ When working with such hierarchical structures the configuration keys
+ used to query properties can have an extended syntax. All components
of a key can be appended by a numerical value in parentheses that
- determines the index of the affected property. This is explained best
- by some examples:
+ determines the index of the affected property. So if we have two
+ <code>table</code> elements we can exactly specify, which one we
+ want to address by appending the corresponding index. This is
+ explained best by some examples:
</p>
<p>
We will now provide some configuration keys and show the results
@@ -243,13 +218,161 @@
Because each configuration key can contain an arbitrary number
of indices it is possible to navigate through complex structures of
XML documents; each XML element can be uniquely identified.
- So at the end of this section we can draw the following facit:
- For simple XML documents that define only some simple properties
- and do not have a complex structure the default XML configuration
- class is suitable. If documents are more complex and their structure
- is important, the hierarchy aware class should be used, which is
- enabled by an additional <code>className</code> attribute as
- shown in the example configuration definition file above.
+ </p>
+ <p>
+ <b>Note:</b> In earlier versions of Configuration there have been
+ two different Configuration classes for dealing with XML documents:
+ <code>XMLConfiguration</code> that did not support the extended
+ query syntax described above and <code>HierarchicalXMLConfiguration</code>,
+ which could operate on truely hierarchical structures. These classes
+ have now been merged into a single class with the name
+ <code>XMLConfiguration</code>, which now supports all types of XML
+ documents. So there is no longer the need to select one of the
+ XML configurations; <code>XMLConfiguration</code> is always the
+ right (and only) choice. The <code><hierarchicalXml></code>
+ XML element that was used in the configuration definition
+ files for <code>ConfigurationFactory</code> to create an instance
+ of <code>HierarchicalXMLConfiguration</code> is now deprecated.
+ </p>
+ </subsection>
+ <subsection name="Adding new properties">
+ <p>
+ So far we have learned how to use indices to avoid ambiguities when
+ querying properties. The same problem occurs when adding new
+ properties to a structured configuration. As an example let's
+ assume we want to add a new field to the second table. New properties
+ can be added to a configuration using the <code>addProperty()</code>
+ method. Of course, we have to exactly specify where in the tree like structure new
+ data is to be inserted. A statement like
+ </p>
+ <source><![CDATA[
+// Warning: This might cause trouble!
+config.addProperty("tables.table.fields.field.name", "size");
+]]></source>
+ <p>
+ would not be sufficient because it does not contain all needed
+ information. How is such a statement processed by the
+ <code>addProperty()</code> method?
+ </p>
+ <p>
+ <code>addProperty()</code> splits the provided key into its
+ single parts and navigates through the properties tree along the
+ corresponding element names. In this example it will start at the
+ root element and then find the <code>tables</code> element. The
+ next key part to be processed is <code>table</code>, but here a
+ problem occurs: the configuration contains two <code>table</code>
+ properties below the <code>tables</code> element. To get rid off
+ this ambiguity an index can be specified at this position in the
+ key that makes clear, which of the two properties should be
+ followed. <code>tables.table(1).fields.field.name</code> e.g.
+ would select the second <code>table</code> property. If an index
+ is missing, <code>addProperty()</code> always follows the last
+ available element. In our example this would be the second
+ <code>table</code>, too.
+ </p>
+ <p>
+ The following parts of the key are processed in exactly the same
+ manner. Under the selected <code>table</code> property there is
+ exactly one <code>fields</code> property, so this step is not
+ problematic at all. In the next step the <code>field</code> part
+ has to be processed. At the actual position in the properties tree
+ there are multiple <code>field</code> (sub) properties. So we here
+ have the same situation as for the <code>table</code> part.
+ Because no explicit index is defined the last <code>field</code>
+ property is selected. The last part of the key passed to
+ <code>addProperty()</code> (<code>name</code> in this example)
+ will always be added as new property at the position that has
+ been reached in the former processing steps. So in our example
+ the last <code>field</code> property of the second table would
+ be given a new <code>name</code> sub property and the resulting
+ structure would look like the following listing:
+ </p>
+ <source><![CDATA[
+ ...
+ <table tableType="application">
+ <name>documents</name>
+ <fields>
+ <field>
+ <name>docid</name>
+ <type>long</type>
+ </field>
+ <field>
+ <name>name</name>
+ <type>java.lang.String</type>
+ </field>
+ <field>
+ <name>creationDate</name>
+ <type>java.util.Date</type>
+ </field>
+ <field>
+ <name>authorID</name>
+ <type>long</type>
+ </field>
+ <field>
+ <name>version</name>
+ <name>size</name> <== Newly added property
+ <type>int</type>
+ </field>
+ </fields>
+ </table>
+ </tables>
+</database>
+]]></source>
+ <p>
+ This result is obviously not what was desired, but it demonstrates
+ how <code>addProperty()</code> works: the method follows an
+ existing branch in the properties tree and adds new leaves to it.
+ (If the passed in key does not match a branch in the existing tree,
+ a new branch will be added. E.g. if we pass the key
+ <code>tables.table.data.first.test</code>, the existing tree can be
+ navigated until the <code>data</code> part of the key. From here a
+ new branch is started with the remaining parts <code>data</code>,
+ <code>first</code> and <code>test</code>.)
+ </p>
+ <p>
+ If we want a different behavior, we must explicitely tell
+ <code>addProperty()</code> what to do. In our example with the
+ new field our intension was to create a new branch for the
+ <code>field</code> part in the key, so that a new <code>field</code>
+ property is added to the structure rather than adding sub properties
+ to the last existing <code>field</code> property. This can be
+ achieved by specifying the special index <code>(-1)</code> at the
+ corresponding position in the key as shown below:
+ </p>
+ <source><![CDATA[
+config.addProperty("tables.table(1).fields.field(-1).name", "size");
+config.addProperty("tables.table(1).fields.field.type", "int");
+]]></source>
+ <p>
+ The first line in this fragment specifies that a new branch is
+ to be created for the <code>field</code> property (index -1).
+ In the second line no index is specified for the field, so the
+ last one is used - which happens to be the field that has just
+ been created. So these two statements add a fully defined field
+ to the second table. This is the default pattern for adding new
+ properties or whole hierarchies of properties: first create a new
+ branch in the properties tree and then populate its sub properties.
+ As an additional example let's add a complete new table definition
+ to our example configuration:
+ </p>
+ <source><![CDATA[
+// Add a new table element and define the name
+config.addProperty("tables.table(-1).name", "versions");
+
+// Add a new field to the new table
+// (an index for the table is not necessary because the latest is used)
+config.addProperty("tables.table.fields.field(-1).name", "id");
+config.addProperty("tables.table.fields.field.type", "int");
+
+// Add another field to the new table
+config.addProperty("tables.table.fields.field(-1).name", "date");
+config.addProperty("tables.table.fields.field.type", "java.sql.Date");
+...
+]]></source>
+ <p>
+ For more information about adding properties to a hierarchical
+ configuration also have a look at the javadocs for
+ <code>HierarchicalConfiguration</code>.
</p>
</subsection>
</section>
@@ -343,8 +466,8 @@
</override>
<additional>
- <hierarchicalXml fileName="tables.xml"/>
- <hierarchicalXml fileName="tasktables.xml" at="tables"/>
+ <xml fileName="tables.xml"/>
+ <xml fileName="tasktables.xml" at="tables"/>
</additional>
</configuration>
]]></source>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org