1

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 Answers2

0

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"/>
M A
  • 71,713
  • 13
  • 134
  • 174
  • Ah yes, well spotted - I didn't realise you can declare a 'var' and use it in place of a property. That explains why the debug didn't match the output to file but the output is still wrong. There seems to be a problem calling xmltask twice in a row (not in for loop) - perhaps file locking? In the end I used a mixture of echo xml in the loop and xmltask after the loop to add namespaces that echxml doesn't add – andy wickson May 21 '15 at 09:57
0

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.

Community
  • 1
  • 1
Patrice M.
  • 4,209
  • 2
  • 27
  • 36