|
|
@@ -0,0 +1,193 @@ |
|
|
|
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
|
|
|
<html><head><title>XmlNamespaceSupport</title></head> |
|
|
|
<body> |
|
|
|
<h2><a name="namespace">XML Namespace Support</a></h2> |
|
|
|
Ant 1.6 introduces support for XML namespaces. |
|
|
|
<h2>History</h2> |
|
|
|
|
|
|
|
<p> |
|
|
|
All releases of Ant prior to Ant 1.6 do not support XML namespaces. |
|
|
|
No support basically implies two things here: |
|
|
|
</p> |
|
|
|
<ul> |
|
|
|
<li> Element names correspond to the "qname" of the tags, which is |
|
|
|
usually the same as the local name. But if the build file writer uses |
|
|
|
colons in names of defined tasks/types, those become part of the |
|
|
|
element name. Turning on namespace support gives colon-separated |
|
|
|
prefixes in tag names a special meaning, and thus build files using |
|
|
|
colons in user-defined tasks and types will break. |
|
|
|
</li> |
|
|
|
<li> Attributes with the names 'xmlns' and 'xmlns:<prefix>' |
|
|
|
are not treated specially, which means that custom tasks and types have |
|
|
|
actually been able to use such attributes as parameter names. Again, |
|
|
|
such tasks/types are going to break when namespace support is enabled |
|
|
|
on the parser. |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
<p>Use of colons in element names has been discouraged in the past |
|
|
|
IIRC, and using any attribute starting with "xml" is actually strongly |
|
|
|
discouraged by the XML spec to reserve such names for future use. |
|
|
|
</p> |
|
|
|
<h2>Motivation</h2> |
|
|
|
|
|
|
|
<p>In build files using a lot of custom and third-party tasks, it is |
|
|
|
easy to get into name conflicts. When individual types are defined, the |
|
|
|
build file writer can do some name-spacing manually (for example, using |
|
|
|
"tomcat-deploy" instead of just "deploy"). But when defining whole |
|
|
|
libraries of types using the <typedef> 'resource' attribute, the |
|
|
|
build file writer has no chance to override or even prefix the names |
|
|
|
supplied by the library. </p> |
|
|
|
<h2>Assigning Namespaces</h2> |
|
|
|
|
|
|
|
<p> |
|
|
|
Adding a 'prefix' attribute to <typedef> might have been enough, |
|
|
|
but XML already has a well-known method for name-spacing. Thus, instead |
|
|
|
of adding a 'prefix' attribute, the <typedef> and <taskdef> |
|
|
|
tasks get a 'uri' attribute, which stores the URI of the XML namespace |
|
|
|
with which the type should be associated: |
|
|
|
</p><pre> <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/> |
|
|
|
<my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
... |
|
|
|
</my:task> |
|
|
|
</pre> |
|
|
|
<p>As the above example demonstrates, the namespace URI needs to be |
|
|
|
specified at least twice: one time as the value of the 'uri' attribute, |
|
|
|
and another time to actually map the namespace to occurrences of |
|
|
|
elements from that namespace, by using the 'xmlns' attribute. This |
|
|
|
mapping can happen at any level in the build file: |
|
|
|
</p><pre> <project name="test" xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
<typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/> |
|
|
|
<my:task> |
|
|
|
... |
|
|
|
</my:task> |
|
|
|
</project> |
|
|
|
</pre> |
|
|
|
<p> |
|
|
|
Use of a namespace prefix is of course optional. Therefore |
|
|
|
the example could also look like this: |
|
|
|
</p><pre> <project name="test"> |
|
|
|
<typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/> |
|
|
|
<task xmlns="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
... |
|
|
|
</task> |
|
|
|
</project> |
|
|
|
</pre> |
|
|
|
<p> |
|
|
|
Here, the namespace is set as the default namespace for the <task> |
|
|
|
element and all its descendants. |
|
|
|
</p> |
|
|
|
<h2>Default namespace</h2> |
|
|
|
<p> |
|
|
|
The default namespace used by Ant is "antlib:org.apache.tools.ant". |
|
|
|
</p> |
|
|
|
<pre> |
|
|
|
<typedef resource="org/example/tasks.properties" uri="antlib:org.apache.tools.ant"/> |
|
|
|
<task> |
|
|
|
.... |
|
|
|
</task> |
|
|
|
</pre> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Namespaces and Nested Elements</h2> |
|
|
|
|
|
|
|
<p>Almost always in Ant 1.6, elements nested inside a namespaced |
|
|
|
element have the same namespace as their parent. So if 'task' in the |
|
|
|
example above allowed a nested 'config' element, the build file snippet |
|
|
|
would look like this: |
|
|
|
</p><pre> <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/> |
|
|
|
<my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
<my:config a="foo" b="bar"/> |
|
|
|
... |
|
|
|
</my:task> |
|
|
|
</pre> |
|
|
|
<p>If the element allows or requires a lot of nested elements, the |
|
|
|
prefix needs to be used for every nested element. Making the namespace |
|
|
|
the default can reduce the verbosity of the script: |
|
|
|
</p><pre> <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/> |
|
|
|
<task xmlns="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
<config a="foo" b="bar"/> |
|
|
|
... |
|
|
|
</task> |
|
|
|
</pre> |
|
|
|
<h2>Namespaces and Attributes</h2> |
|
|
|
|
|
|
|
<p> |
|
|
|
Attributes are only used to configure the element they belong to if: |
|
|
|
</p> |
|
|
|
<ul> |
|
|
|
<li> they have no namespace (note that the default namespace does *not* apply to attributes) |
|
|
|
</li> |
|
|
|
<li> they are in the same namespace as the element they belong to |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
<p> |
|
|
|
Other attributes are simply ignored. |
|
|
|
</p> |
|
|
|
<p> |
|
|
|
This means that both: |
|
|
|
</p> |
|
|
|
<p> |
|
|
|
</p><pre> <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
<my:config a="foo" b="bar"/> |
|
|
|
... |
|
|
|
</my:task> |
|
|
|
</pre> |
|
|
|
<p> |
|
|
|
and |
|
|
|
</p> |
|
|
|
<pre> <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"> |
|
|
|
<my:config my:a="foo" my:b="bar"/> |
|
|
|
... |
|
|
|
</my:task> |
|
|
|
</pre> |
|
|
|
<p> |
|
|
|
result in the parameters "a" and "b" being used as parameters to configure the nested "config" element. |
|
|
|
</p> |
|
|
|
<p>It also means that you can use attributes from other namespaces |
|
|
|
to markup the build file with extra meta data, such as RDF and |
|
|
|
XML-Schema (whether that's a good thing or not). The same is not true |
|
|
|
for elements from unknown namespaces, which result in a error. |
|
|
|
</p> |
|
|
|
<h2>Mixing Elements from Different Namespaces</h2> |
|
|
|
|
|
|
|
<p>Now comes the difficult part: elements from different namespaces can |
|
|
|
be woven together under certain circumstances. This has a lot to do |
|
|
|
with the Ant 1.6 |
|
|
|
<a href="../develop.html#nestedtype">add type introspection rules</a>: |
|
|
|
Ant types and tasks are now free to accept arbritrary named types as |
|
|
|
nested elements, as long as the concrete type implements the interface |
|
|
|
expected by the task/type. The most obvioius example for this is the |
|
|
|
<condition> task, which supports various nested conditions, all |
|
|
|
of which extend the interface <tt>Condition</tt>. To integrate a |
|
|
|
custom condition in Ant, you can now simply <typedef> the |
|
|
|
condition, and then use it anywhere develop.html#nestedtypwhere conditions are allowed |
|
|
|
(assuming the containing element has a generic <tt>add(Condition)</tt> or <tt>addConfigured(Configured)</tt>method): |
|
|
|
</p><pre> <typedef resource="org/example/conditions.properties" uri="<a href="http://example.org/conditions">http://example.org/conditions</a>"/> |
|
|
|
<condition property="prop" xmlns="<a href="http://example.org/conditions">http://example.org/conditions</a>"> |
|
|
|
<and> |
|
|
|
<available file="bla.txt"/> |
|
|
|
<my:condition a="foo"/> |
|
|
|
</and> |
|
|
|
</condition> |
|
|
|
</pre> |
|
|
|
<p> |
|
|
|
In Ant 1.6, this feature cannot be used as much as we'd all like to: a |
|
|
|
lot of code has not yet been adapted to the new introspection rules, |
|
|
|
and elements like the builtin Ant conditions and selectors are not |
|
|
|
really types in 1.6. This is expected to change in Ant 1.7. |
|
|
|
</p> |
|
|
|
<h2>Namespaces and Antlib</h2> |
|
|
|
|
|
|
|
<p> |
|
|
|
The new <a href="antlib.html">AntLib</a> |
|
|
|
feature is also very much integrated with the namespace support in Ant |
|
|
|
1.6. Basically, you can "import" Antlibs simply by using a special |
|
|
|
scheme for the namespace URI: the <tt>antlib</tt> scheme, which expects the package name in which a special <tt>antlib.xml</tt> file is located. |
|
|
|
</p> |
|
|
|
<hr> |
|
|
|
<p align="center">Copyright © 2003 Apache Software |
|
|
|
Foundation. All rights Reserved.</p> |
|
|
|
|
|
|
|
</body> |
|
|
|
</html> |