mirror of
https://github.com/apache/ant.git
synced 2025-05-17 21:45:12 +00:00
225 lines
9.5 KiB
HTML
225 lines
9.5 KiB
HTML
<!DOCTYPE html>
|
|
<!--
|
|
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
|
|
|
|
https://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.
|
|
-->
|
|
<html lang="en">
|
|
<head>
|
|
<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
|
|
<title>XmlNamespaceSupport</title>
|
|
</head>
|
|
<body>
|
|
<h2 id="namespace">XML Namespace Support</h2>
|
|
Apache Ant 1.6 introduces support for XML namespaces.
|
|
<h3>History</h3>
|
|
|
|
<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 <q>xmlns</q> and <q>xmlns:<em>prefix</em></q> 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, and using any attribute
|
|
starting with <q>xml</q> is actually strongly discouraged by the XML spec to reserve such
|
|
names for future use.
|
|
</p>
|
|
|
|
<h3>Motivation</h3>
|
|
<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
|
|
namespacing manually (for example, using <q>tomcat-deploy</q> instead of
|
|
just <q>deploy</q>). But when defining whole libraries of types using
|
|
the <code><typedef></code> <var>resource</var> attribute, the build file writer has
|
|
no chance to override or even prefix the names supplied by the library.</p>
|
|
|
|
<h3>Assigning Namespaces</h3>
|
|
<p>
|
|
Adding a <var>prefix</var> attribute to <code><typedef></code> might have been
|
|
enough, but XML already has a well-known method for namespacing. Thus, instead of adding
|
|
a <var>prefix</var> attribute, the <code><typedef></code>
|
|
and <code><taskdef></code> tasks get a <var>uri</var> 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="http://example.org/tasks"/>
|
|
<my:task xmlns:my="http://example.org/tasks">
|
|
...
|
|
</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 <var>uri</var> attribute, and another time to actually
|
|
map the namespace to occurrences of elements from that namespace, by using
|
|
the <var>xmlns</var> attribute. This mapping can happen at any level in the build file:
|
|
</p>
|
|
<pre>
|
|
<project name="test" xmlns:my="http://example.org/tasks">
|
|
<typedef resource="org/example/tasks.properties" uri="http://example.org/tasks"/>
|
|
<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="http://example.org/tasks"/>
|
|
<task xmlns="http://example.org/tasks">
|
|
...
|
|
</task>
|
|
</project></pre>
|
|
<p>
|
|
Here, the namespace is set as the default namespace for the <code><task></code>
|
|
element and all its descendants.
|
|
</p>
|
|
|
|
<h3>Default Namespace</h3>
|
|
<p>
|
|
The default namespace used by Ant is <code>antlib:org.apache.tools.ant</code>.
|
|
</p>
|
|
<pre>
|
|
<typedef resource="org/example/tasks.properties" uri="antlib:org.apache.tools.ant"/>
|
|
<task>
|
|
...
|
|
</task></pre>
|
|
|
|
<h3>Namespaces and Nested Elements</h3>
|
|
<p>
|
|
Almost always in Ant 1.6, elements nested inside a namespaced element have the same
|
|
namespace as their parent. So if <code>task</code> in the example above allowed a
|
|
nested <code>config</code> element, the build file snippet would look like this:
|
|
</p>
|
|
<pre>
|
|
<typedef resource="org/example/tasks.properties" uri="http://example.org/tasks"/>
|
|
<my:task xmlns:my="http://example.org/tasks">
|
|
<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="http://example.org/tasks"/>
|
|
<task xmlns="http://example.org/tasks">
|
|
<config a="foo" b="bar"/>
|
|
...
|
|
</task></pre>
|
|
<p>
|
|
<em>Since Ant 1.6.2</em>, elements nested inside a namespaced element may also be in Ant's
|
|
default namespace. This means that the following is now allowed:
|
|
</p>
|
|
<pre>
|
|
<typedef resource="org/example/tasks.properties"
|
|
uri="http://example.org/tasks"/>
|
|
<my:task xmlns:my="http://example.org/tasks">
|
|
<config a="foo" b="bar"/>
|
|
...
|
|
</my:task></pre>
|
|
|
|
<h3>Namespaces and Attributes</h3>
|
|
<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 <strong>not</strong> apply to attributes)</li>
|
|
<li>they are in the same namespace as the element they belong to</li>
|
|
</ul>
|
|
<p>
|
|
<em>Since Ant 1.9.1</em> two attribute namespaces <code>ant:if</code>
|
|
and <code>ant:unless</code> are available to allow you to insert elements conditionally.
|
|
</p>
|
|
<p>
|
|
Other attributes are simply ignored.
|
|
</p>
|
|
<p>
|
|
This means that both:
|
|
</p>
|
|
<p>
|
|
</p>
|
|
<pre>
|
|
<my:task xmlns:my="http://example.org/tasks">
|
|
<my:config a="foo" b="bar"/>
|
|
...
|
|
</my:task></pre>
|
|
<p>
|
|
and
|
|
</p>
|
|
<pre>
|
|
<my:task xmlns:my="http://example.org/tasks">
|
|
<my:config my:a="foo" my:b="bar"/>
|
|
...
|
|
</my:task></pre>
|
|
<p>
|
|
result in the parameters <var>a</var> and <var>b</var> being used as parameters to
|
|
configure the nested <code>config</code> element.
|
|
</p>
|
|
<p>
|
|
It also means that you can use attributes from other namespaces to markup the build file
|
|
with extra metadata, 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>
|
|
<h3>Mixing Elements from Different Namespaces</h3>
|
|
|
|
<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 arbitrary named types as nested elements, as long as the concrete type
|
|
implements the interface expected by the task/type. The most obvious example for this is
|
|
the <code><condition></code> task, which supports various nested conditions, all of
|
|
which extend the interface <code class="code">Condition</code>. To integrate a custom
|
|
condition in Ant, you can now simply <code><typedef></code> the condition, and then use
|
|
it anywhere nested conditions are allowed (assuming the containing element has a
|
|
generic <code class="code">add(Condition)</code>
|
|
or <code class="code">addConfigured(Condition)</code> method):
|
|
</p>
|
|
<pre>
|
|
<typedef resource="org/example/conditions.properties" uri="http://example.org/conditions"/>
|
|
<condition property="prop" xmlns="http://example.org/conditions">
|
|
<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 Ant's built-in
|
|
conditions and selectors are not really types in 1.6. This is expected to change in Ant
|
|
1.7.
|
|
</p>
|
|
<h3>Namespaces and Antlib</h3>
|
|
|
|
<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 <code>antlib</code> scheme, which expects the
|
|
package name in which a special <samp>antlib.xml</samp> file is located.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|