antelementmacrodef

Ant macrodef: Is there a way to get the contents of an element parameter?


I'm trying to debug a macrodef in Ant. I cannot seem to find a way to display the contents of a parameter sent as an element.

<project name='debug.macrodef'>
  <macrodef name='def.to.debug'>
    <attribute name='attr' />
    <element name='elem' />
    <sequential>
      <echo>Sure, the attribute is easy to debug: @{attr}</echo>
      <echo>The element works only in restricted cases: <elem /> </echo>
      <!-- This works only if <elem /> doesn't contain anything but a
           textnode, if there were any elements in there echo would
           complain it doesn't understand them. -->
    </sequential>
  </macrodef>

  <target name='works'>
    <def.to.debug attr='contents of attribute'>
      <elem>contents of elem</elem>
    </def.to.debug>
  </target>

  <target name='does.not.work'>
    <def.to.debug attr='contents of attribute'>
      <elem><sub.elem>contents of sub.elem</sub.elem></elem>
    </def.to.debug>
  </target>
</project>

Example run:

$ ant works
...
works:
 [echo] Sure, the attribute is easy to debug: contents of attribute
 [echo] The element works only in restricted cases:  contents of elem
...

$ ant does.not.work
...
does.not.work:
 [echo] Sure, the attribute is easy to debug: contents of attribute

BUILD FAILED
.../build.xml:21: The following error occurred while executing this line:
.../build.xml:7: echo doesn't support the nested "sub.elem" element.
...

So I guess I need either a way to get the contents of the <elem /> into a property somehow (some extended macrodef implementation might have that), or I need a sort of <element-echo><elem /></element-echo> that could print out whatever XML tree you put inside. Does anyone know of an implementation of either of these? Any third, unanticipated way of getting the data out is of course also welcome.


Solution

  • How about the echoxml task?

    In your example build file replacing the line

    <echo>The element works only in restricted cases: <elem /> </echo>
    

    with

    <echoxml><elem /></echoxml>
    

    results in

    $ ant does.not.work
    ...
    does.not.work:
         [echo] Sure, the attribute is easy to debug: contents of attribute
    <?xml version="1.0" encoding="UTF-8"?>
    <sub.elem>contents of sub.elem</sub.elem>
    

    Perhaps the XML declaration is not wanted though. You might use the echoxml file attribute to put the output to a temporary file, then read that file and remove the declaration, or reformat the information as you see fit.

    edit

    On reflection, you can probably get close to what you describe, for example this sequential body of your macrodef

    <sequential>
      <echo>Sure, the attribute is easy to debug: @{attr}</echo>
      <echoxml file="macro_elem.xml"><elem /></echoxml>
      <loadfile property="elem" srcFile="macro_elem.xml">
        <filterchain>
          <LineContainsRegexp negate="yes">
          <regexp pattern=".xml version=.1.0. encoding=.UTF-8..." />
          </LineContainsRegexp>
        </filterchain>
      </loadfile>
      <echo message="${elem}" />
    </sequential>
    

    gives

    $ ant does.not.work
    ...
    does.not.work:
         [echo] Sure, the attribute is easy to debug: contents of attribute
         [echo] <sub.elem>contents of sub.elem</sub.elem>