1 | <!--
|
---|
2 | Licensed to the Apache Software Foundation (ASF) under one or more
|
---|
3 | contributor license agreements. See the NOTICE file distributed with
|
---|
4 | this work for additional information regarding copyright ownership.
|
---|
5 | The ASF licenses this file to You under the Apache License, Version 2.0
|
---|
6 | (the "License"); you may not use this file except in compliance with
|
---|
7 | the License. You may obtain a copy of the License at
|
---|
8 |
|
---|
9 | http://www.apache.org/licenses/LICENSE-2.0
|
---|
10 |
|
---|
11 | Unless required by applicable law or agreed to in writing, software
|
---|
12 | distributed under the License is distributed on an "AS IS" BASIS,
|
---|
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
14 | See the License for the specific language governing permissions and
|
---|
15 | limitations under the License.
|
---|
16 | -->
|
---|
17 | <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
---|
18 | <html><head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
|
---|
19 | <title>XmlNamespaceSupport</title></head>
|
---|
20 | <body>
|
---|
21 | <h2><a name="namespace">XML Namespace Support</a></h2>
|
---|
22 | Ant 1.6 introduces support for XML namespaces.
|
---|
23 | <h3>History</h3>
|
---|
24 |
|
---|
25 | <p>
|
---|
26 | All releases of Ant prior to Ant 1.6 do not support XML namespaces.
|
---|
27 | No support basically implies two things here:
|
---|
28 | </p>
|
---|
29 | <ul>
|
---|
30 | <li> Element names correspond to the "qname" of the tags, which is
|
---|
31 | usually the same as the local name. But if the build file writer uses
|
---|
32 | colons in names of defined tasks/types, those become part of the
|
---|
33 | element name. Turning on namespace support gives colon-separated
|
---|
34 | prefixes in tag names a special meaning, and thus build files using
|
---|
35 | colons in user-defined tasks and types will break.
|
---|
36 | </li>
|
---|
37 | <li> Attributes with the names 'xmlns' and 'xmlns:<code><prefix></code>'
|
---|
38 | are not treated specially, which means that custom tasks and types have
|
---|
39 | actually been able to use such attributes as parameter names. Again,
|
---|
40 | such tasks/types are going to break when namespace support is enabled
|
---|
41 | on the parser.
|
---|
42 | </li>
|
---|
43 | </ul>
|
---|
44 | <p>Use of colons in element names has been discouraged in the past,
|
---|
45 | and using any attribute starting with "xml" is actually strongly
|
---|
46 | discouraged by the XML spec to reserve such names for future use.
|
---|
47 | </p>
|
---|
48 | <h3>Motivation</h3>
|
---|
49 |
|
---|
50 | <p>In build files using a lot of custom and third-party tasks, it is
|
---|
51 | easy to get into name conflicts. When individual types are defined, the
|
---|
52 | build file writer can do some namespacing manually (for example, using
|
---|
53 | "tomcat-deploy" instead of just "deploy"). But when defining whole
|
---|
54 | libraries of types using the <code><typedef></code> 'resource' attribute, the
|
---|
55 | build file writer has no chance to override or even prefix the names
|
---|
56 | supplied by the library. </p>
|
---|
57 | <h3>Assigning Namespaces</h3>
|
---|
58 |
|
---|
59 | <p>
|
---|
60 | Adding a 'prefix' attribute to <code><typedef></code> might have been enough,
|
---|
61 | but XML already has a well-known method for namespacing. Thus, instead
|
---|
62 | of adding a 'prefix' attribute, the <code><typedef></code> and <code><taskdef></code>
|
---|
63 | tasks get a 'uri' attribute, which stores the URI of the XML namespace
|
---|
64 | with which the type should be associated:
|
---|
65 | </p><pre> <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/>
|
---|
66 | <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
67 | ...
|
---|
68 | </my:task>
|
---|
69 | </pre>
|
---|
70 | <p>As the above example demonstrates, the namespace URI needs to be
|
---|
71 | specified at least twice: one time as the value of the 'uri' attribute,
|
---|
72 | and another time to actually map the namespace to occurrences of
|
---|
73 | elements from that namespace, by using the 'xmlns' attribute. This
|
---|
74 | mapping can happen at any level in the build file:
|
---|
75 | </p><pre> <project name="test" xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
76 | <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/>
|
---|
77 | <my:task>
|
---|
78 | ...
|
---|
79 | </my:task>
|
---|
80 | </project>
|
---|
81 | </pre>
|
---|
82 | <p>
|
---|
83 | Use of a namespace prefix is of course optional. Therefore
|
---|
84 | the example could also look like this:
|
---|
85 | </p><pre> <project name="test">
|
---|
86 | <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/>
|
---|
87 | <task xmlns="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
88 | ...
|
---|
89 | </task>
|
---|
90 | </project>
|
---|
91 | </pre>
|
---|
92 | <p>
|
---|
93 | Here, the namespace is set as the default namespace for the <code><task></code>
|
---|
94 | element and all its descendants.
|
---|
95 | </p>
|
---|
96 | <h3>Default namespace</h3>
|
---|
97 | <p>
|
---|
98 | The default namespace used by Ant is "antlib:org.apache.tools.ant".
|
---|
99 | </p>
|
---|
100 | <pre>
|
---|
101 | <typedef resource="org/example/tasks.properties" uri="antlib:org.apache.tools.ant"/>
|
---|
102 | <task>
|
---|
103 | ....
|
---|
104 | </task>
|
---|
105 | </pre>
|
---|
106 |
|
---|
107 |
|
---|
108 |
|
---|
109 | <h3>Namespaces and Nested Elements</h3>
|
---|
110 |
|
---|
111 | <p>
|
---|
112 | Almost always in Ant 1.6, elements nested inside a namespaced
|
---|
113 | element have the same namespace as their parent. So if 'task' in the
|
---|
114 | example above allowed a nested 'config' element, the build file snippet
|
---|
115 | would look like this:
|
---|
116 | </p><pre> <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/>
|
---|
117 | <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
118 | <my:config a="foo" b="bar"/>
|
---|
119 | ...
|
---|
120 | </my:task>
|
---|
121 | </pre>
|
---|
122 | <p>If the element allows or requires a lot of nested elements, the
|
---|
123 | prefix needs to be used for every nested element. Making the namespace
|
---|
124 | the default can reduce the verbosity of the script:
|
---|
125 | </p><pre> <typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/>
|
---|
126 | <task xmlns="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
127 | <config a="foo" b="bar"/>
|
---|
128 | ...
|
---|
129 | </task>
|
---|
130 | </pre>
|
---|
131 | <p>
|
---|
132 | From Ant 1.6.2, elements nested inside a namespaced element may also be
|
---|
133 | in Ant's default namespace. This means that the following is now allowed:
|
---|
134 | </p>
|
---|
135 | </p><pre> <typedef resource="org/example/tasks.properties"
|
---|
136 | uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/>
|
---|
137 | <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
138 | <config a="foo" b="bar"/>
|
---|
139 | ...
|
---|
140 | </my:task>
|
---|
141 | </pre>
|
---|
142 |
|
---|
143 | <h3>Namespaces and Attributes</h3>
|
---|
144 |
|
---|
145 | <p>
|
---|
146 | Attributes are only used to configure the element they belong to if:
|
---|
147 | </p>
|
---|
148 | <ul>
|
---|
149 | <li> they have no namespace (note that the default namespace does *not* apply to attributes)
|
---|
150 | </li>
|
---|
151 | <li> they are in the same namespace as the element they belong to
|
---|
152 | </li>
|
---|
153 | </ul>
|
---|
154 | <p>
|
---|
155 | Other attributes are simply ignored.
|
---|
156 | </p>
|
---|
157 | <p>
|
---|
158 | This means that both:
|
---|
159 | </p>
|
---|
160 | <p>
|
---|
161 | </p><pre> <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
162 | <my:config a="foo" b="bar"/>
|
---|
163 | ...
|
---|
164 | </my:task>
|
---|
165 | </pre>
|
---|
166 | <p>
|
---|
167 | and
|
---|
168 | </p>
|
---|
169 | <pre> <my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>">
|
---|
170 | <my:config my:a="foo" my:b="bar"/>
|
---|
171 | ...
|
---|
172 | </my:task>
|
---|
173 | </pre>
|
---|
174 | <p>
|
---|
175 | result in the parameters "a" and "b" being used as parameters to configure the nested "config" element.
|
---|
176 | </p>
|
---|
177 | <p>It also means that you can use attributes from other namespaces
|
---|
178 | to markup the build file with extra metadata, such as RDF and
|
---|
179 | XML-Schema (whether that's a good thing or not). The same is not true
|
---|
180 | for elements from unknown namespaces, which result in a error.
|
---|
181 | </p>
|
---|
182 | <h3>Mixing Elements from Different Namespaces</h3>
|
---|
183 |
|
---|
184 | <p>Now comes the difficult part: elements from different namespaces can
|
---|
185 | be woven together under certain circumstances. This has a lot to do
|
---|
186 | with the Ant 1.6
|
---|
187 | <a href="../develop.html#nestedtype">add type introspection rules</a>:
|
---|
188 | Ant types and tasks are now free to accept arbritrary named types as
|
---|
189 | nested elements, as long as the concrete type implements the interface
|
---|
190 | expected by the task/type. The most obvious example for this is the
|
---|
191 | <code><condition></code> task, which supports various nested conditions, all
|
---|
192 | of which extend the interface <tt>Condition</tt>. To integrate a
|
---|
193 | custom condition in Ant, you can now simply <code><typedef></code> the
|
---|
194 | condition, and then use it anywhere nested conditions are allowed
|
---|
195 | (assuming the containing element has a generic <tt>add(Condition)</tt> or <tt>addConfigured(Condition)</tt> method):
|
---|
196 | </p><pre> <typedef resource="org/example/conditions.properties" uri="<a href="http://example.org/conditions">http://example.org/conditions</a>"/>
|
---|
197 | <condition property="prop" xmlns="<a href="http://example.org/conditions">http://example.org/conditions</a>">
|
---|
198 | <and>
|
---|
199 | <available file="bla.txt"/>
|
---|
200 | <my:condition a="foo"/>
|
---|
201 | </and>
|
---|
202 | </condition>
|
---|
203 | </pre>
|
---|
204 | <p>
|
---|
205 | In Ant 1.6, this feature cannot be used as much as we'd all like to: a
|
---|
206 | lot of code has not yet been adapted to the new introspection rules,
|
---|
207 | and elements like Ant's built-in conditions and selectors are not
|
---|
208 | really types in 1.6. This is expected to change in Ant 1.7.
|
---|
209 | </p>
|
---|
210 | <h3>Namespaces and Antlib</h3>
|
---|
211 |
|
---|
212 | <p>
|
---|
213 | The new <a href="antlib.html">AntLib</a>
|
---|
214 | feature is also very much integrated with the namespace support in Ant
|
---|
215 | 1.6. Basically, you can "import" Antlibs simply by using a special
|
---|
216 | 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.
|
---|
217 | </p>
|
---|
218 |
|
---|
219 | </body>
|
---|
220 | </html>
|
---|