| <!-- |
| 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. |
| --> |
| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
| <html><head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> |
| <title>XmlNamespaceSupport</title></head> |
| <body> |
| <h2><a name="namespace">XML Namespace Support</a></h2> |
| 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 'xmlns' and 'xmlns:<code><prefix></code>' |
| 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 "xml" 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 |
| "tomcat-deploy" instead of just "deploy"). But when defining whole |
| libraries of types using the <code><typedef></code> 'resource' 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 'prefix' attribute to <code><typedef></code> might have been enough, |
| but XML already has a well-known method for namespacing. Thus, instead |
| of adding a 'prefix' attribute, the <code><typedef></code> and <code><taskdef></code> |
| 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 <code><task></code> |
| element and all its descendants. |
| </p> |
| <h3>Default namespace</h3> |
| <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> |
| |
| |
| |
| <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 '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> |
| <p> |
| From Ant 1.6.2, elements nested inside a namespaced element may also be |
| in Ant's default namespace. This means that the following is now allowed: |
| </p> |
| </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>"> |
| <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 *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 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 arbritrary 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 <tt>Condition</tt>. 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 <tt>add(Condition)</tt> or <tt>addConfigured(Condition)</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 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 <tt>antlib</tt> scheme, which expects the package name in which a special <tt>antlib.xml</tt> file is located. |
| </p> |
| |
| </body> |
| </html> |