Unexpected output when running Xmltask in ant for loop

373 Views Asked by At

I am trying to iterate over a bunch of files in a directory and create an xml document from their file names. Here's the code (taskdefs omitted):

    <target name="test1">

        <for param="file">
            <path>
                <fileset dir="${basedir}/schemas" includes="*.xsd" />
            </path>
            <sequential>
                <echo message="found file  .....@{file}" />
                <xmltask source="wiki.xml" dest="wiki.xml" outputter="simple:4">

                    <insert path="//exported" position="after">
                        <![CDATA[
                                <exported Id="@{file}" />
                        ]]>
                    </insert>
                </xmltask>

                <echo message="------------------------------"/>
                <loadfile property="mymess"
                  srcFile="wiki.xml"/>
                <echo message="${mymess}"/>
                <echo message="------------------------------"/>
        </sequential>
    </for>
</target>
</project>

The initial source file wiki.xml looks like:

<top>
    <exported Id="Animal_v1"></exported>
</top>

This is the debug output:

test1:
     [echo] found file  .....C:\temp\BranchBS_v1.xsd
     [echo] ------------------------------------------------------------
     [echo] <?xml version="1.0" encoding="UTF-8" standalone="no"?>
     [echo]
     [echo] <top>
     [echo]     <exported Id="Animal_v1"></exported>
     [echo]     <exported Id="C:\temp\schemas\BranchBS_v1.xsd"></exported>
     [echo] </top>
     [echo]
     [echo] ------------------------------------------------------------
     [echo] found file  .....C:\temp\schemas\CalendarEvent_v1.xsd
     [echo] ------------------------------------------------------------
     [echo] <?xml version="1.0" encoding="UTF-8" standalone="no"?>
     [echo]
     [echo] <top>
     [echo]     <exported Id="/Animal_v1"></exported>
     [echo]     <exported Id="C:\temp\schemas\BranchBS_v1.xsd"></exported>
     [echo] </top>
     [echo]
     [echo] ------------------------------------------------------------

This shows that the first pass was correct: it found the 'seed' entry (Animal) plus the one just added (Branch). The debug output looks like the second pass didn't happen because it's the same as the first, but when I actually look at the content s of wiki.xml when the script has completed, it looks like this:

<top>
    <exported Id="Animal_v1"></exported>
    <exported instanceId="C:\temp\schemas\CalendarEvent_v1.xsd"></exported>
    <exported instanceId="C:\temp\schemas\BranchBS_v1.xsd"></exported>
    <exported instanceId="C:\temp\schemas\CalendarEvent_v1.xsd"></exported>
</top>

So not only did it write the CalendarEvent record (missing from the debug) but it did it twice!

I am truly baffled.

2

There are 2 best solutions below

1
On

An Ant property is immutable -- the value of ${mymess} will not change once the first time it is loaded with the contents of the file. Since you're using ant-contrib, you can unset the property before loading using the var task:

<var name="mymess" unset="true" />
<loadfile property="mymess" srcFile="wiki.xml"/>
0
On

As reported by @manouti, for debugging you are reusing an immutable property in a loop therefore its value won't change. Simple solution: use the 'local' ant task, e.g.:

            <echo message="------------------------------"/>
            <local name="mymess"/> <!-- declares a local scope for "mymess" -->
            <loadfile property="mymess"
              srcFile="wiki.xml"/>
            <echo message="${mymess}"/>
            <echo message="------------------------------"/>

Your second problem has to do with your xpath syntax, you're asking xmltask to insert a node after EACH pre-existing "exported" nodes. Hence the second time around, you insert twice. Instead you want:

             <insert path="//exported[last()]" position="after">

See this other SO question for instance.