ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Reilly <peter.rei...@corvil.com>
Subject Re: <macro> and XML NS hell ;-)
Date Wed, 03 Mar 2004 09:16:15 GMT
Sorry Gus,
I meant to respond earlier but I am moving to a new computer
and some things got lost.

The main reason the example is confusing is that macrodef, despite
it's name, does not do real textual  substition, it sees a Dom like tree
of elements (a tree of UnknownElements with paired RuntimeConfigurables)
and not the raw texual angley brackets.

A simple example should make this clear. Assume first that namespaced
xml does not support prefix free elements and there is a class A

class A {
   public void addFileSet(FileSet s) {}
}

and class B:
class B {
   public void addFileSet(FileSet s) {}
}

Now suppose that A is a type a in namespace antlib:net.a
and B is a type b in namespace antlib:net.b.
The following would be correct xml:
<ant:project xmlns:a="antlib:net.a" xmlns:b="antlib:net.b"
             xmnls:ant="antlib:org.apache.tools.ant">
  <a:a>
     <a:fileset dir="."/>
  </a:a>

  <b:b>
     <b:fileset dir="."/>
   </b:b>

</ant:project>

Now it is understandable that the following does not work:

  <ant:macrodef name="c">
     <ant:element name="files">
     <ant:sequential>
         <a:a>
           <ant:files/>
          </a:a>
          <b:b>
            <ant:files/>
          </b:b>
     </ant:sequential>
  </ant:macrodef>

as there is no set of xml dom elements that will be
acceptable to a:a and b:a.

XmlNs does have the concept of a default ns prefix and a not specified ns prefix.

First the default ns prefix.
This is what Dominique tried to use.

  <ant:macrodef name="c">
     <ant:element name="files">
     <ant:sequential>
         <a xmlns="antlib:net.a">
           <ant:files/>
          </a>
          <b xmlns="antlib:net.b">
            <ant:files/>
          </b>
     </ant:sequential>
  </ant:macrodef>

  <ant:c>
    <files xmlns="antlib:org.apache.tools.ant">
       <fileset dir="."/>
     </files>
   </ant:c>

This will fail as the fileset element is in the "antlib:org.apache.tools.ant"
namespace and not in the "antlib:net.a" or "antlib:net.b" namespaces.

The not-specified ns prefix (I think) is proceeded by whatever the xml processor
program likes. Ant treats this like a default xml namespace. 

One solution to this (common) problem would be to allow the a's addFileset method
to be matched by both a's namespace fileset element and by ant's default namespace,
so the following would be correct xml:

<a:a>
  <ant:fileset dir="."/>  <!-- matches A.addFileSet() method -->
</a:a>

and
<a:a>
  <a:fileset dir="."/>  <!-- also matches A.addFileSet() method -->
</a:a>


On a side - issue, I think that this solution would help in the
uptake of antlibs.

ForExample,
a a build file using ant-contrib with ant 1.5 would look like something
like this:

<project default="compile">
  <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
   
  <switch value="${foo}">
    <case value="bar">
      <echo message="The value of property foo is bar" />
    </case>
    <case value="baz">
       <echo message="The value of property foo is baz" />
    </case>
    <default>
      <echo message="The value of property foo is not sensible" />
    </default>
  </switch>
</project>

Using antlib:net.sf.antcontrib namespace in ant 1.6 results in 2/3 lines 
being changed, and one feels like an xml ns lawyer  :-( 
Using the more relaxed rules only involves modifing a couple of lines
and looks (IMO) a lot nicer:
 
<project default="compile" xmlns:ac="antlib:net.sf.antcontrib">
  <ac:switch value="${foo}">
    <case value="bar">
      <echo message="The value of property foo is bar" />
    </case>
    <case value="baz">
       <echo message="The value of property foo is baz" />
    </case>
    <default>
      <echo message="The value of property foo is not sensible" />
    </default>
  </ac:switch>
</project>

Peter

Gus Heck wrote:

> Gus Heck wrote:
>
>>
>>> re given to the elements in the calling macro.
>>>
>>> In ant 1.6.0+, the namespace of elements discovered by reflection take
>>> the namespace uri of type/task that contains the element (Note this 
>>> is the
>>> uri and not the localname).
>>>
>>> The enclosed patch will allow the namespace of nested elements to be
>>> either the ant uri or the namespace of the containing type/task.
>>>
>> I am quite possibly confused but I thought xml namespaces required 
>> that the namespace be
>>
>> 1. The namespace indicated by the specified prefix
>>
>> 2. If there is no prefix, then the current default namespace must be 
>> used. (defined on some containing element, be it the top element or 
>> some other containing element with an xmlns="some uri").
>>
>> If an unprefixed element is taking on a namespace not declared with 
>> xmlns="some uri" (which is different from xmlns:foo="some uri") 
>> aren't we blowing it in implementing namespaces correctly?
>>
>> -Gus
>>
> Was I wrong? Confused? or just ignored?
>
> -Gus
>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
>> For additional commands, e-mail: dev-help@ant.apache.org
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message