Hairi
Hairi

Reputation: 3723

Generate distinct XML elements with XSLT and Ant

I am trying to get set of unique elements command in terms of attribute @name. When I use the XSLT IDE Exchange XML editor it works. But with ant xslt-task it doesn't work. Here is the XSLT:

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">
    <xsl:key name="commandUnique" match="command" use="@name"/>
    <xsl:template match="/">
        <root>
            <xsl:for-each select="//command[generate-id() = generate-id(key('commandUnique', @name)[1])]">
            <xsl:element name="{@name}"/>
            </xsl:for-each>
        </root>
    </xsl:template>
</xsl:stylesheet>

This is the input XML file:

 <commands>
    <command name="get-version"/>
    <command name="answer-get-version"/>
    <command name="get-version"/>
    <command name="read-m-tods"/>
    <command name="read-m-tods"/>
    <command name="answer-read-m-tods"/>
    <command name="answer-read-m-tods"/>
    <command name="get-slave-request"/>
    <command name="answer-get-slave-request"/>
    <command name="answer-read-m-tods"/>
    <command name="write-m-tods"/>
    <command name="answer-write-m-tods"/>
 </commands>

The output indeed is this:

<root/>

The expected output is this:

<root>
   <get-version/>
   <answer-get-version/>
   <read-m-tods/>
   <answer-read-m-tods/>
   <get-slave-request/>
   <answer-get-slave-request/>
   <write-m-tods/>
   <answer-write-m-tods/>
</root>

In the output we have set of all unique pairs command/@name (without repetition).

It is interesting that when I do the transformation using the XSLT IDE I get exactly what I want, but when I use ant I get only <root/>.

Here this is the ant task:

<target name="get-unique-objects">
    <basename property="tod-file-base-name" file="${file}"/>
    <xslt in="${input-file}" out="${output-file-dir}/${tod-file-base-name}-unique-objects.xml" extension=".xml" style="xslt/projects/asp-bus/implementation/xsl/stylesheet-get-unique-properties.xsl">
        <classpath location="../../../../infrastructure/SaxonEE9-7-0-11J/saxon9ee.jar:/net.sf.saxon.TransformerFactoryImpl"/>
    </xslt>
</target>

The ant and the IDE are using different(in terms of version/release) processors. BUT both processors are Saxon and both support XSLT 2 but it somehow works with the one, and doesn't with the other. I tried something simple, just to make sure that the ant task is OK and it worked as well. I suspect the problem has something to do with the generate-id(key(...)) stuff. No warning and errors during the transformation. I get only empty element <root/> at the output (when ran via ant).

Upvotes: 1

Views: 140

Answers (1)

Chad Nouis
Chad Nouis

Reputation: 7051

The following <classpath> looks unusual:

<classpath
    location="../../../../infrastructure/SaxonEE9-7-0-11J/saxon9ee.jar:/net.sf.saxon.TransformerFactoryImpl"/>

Notice the slash (/) at the beginning of /net.sf.saxon.TransformerFactoryImpl. I believe this will cause Ant to look for a file literally named net.sf.saxon.TransformerFactoryImpl under the root directory.

Try replacing the <xslt> task with the following:

<xslt in="${input-file}" out="${output-file-dir}/${tod-file-base-name}-unique-objects.xml" style="xslt/projects/asp-bus/implementation/xsl/stylesheet-get-unique-properties.xsl">
    <classpath location="../../../../infrastructure/SaxonEE9-7-0-11J/saxon9ee.jar"/>
    <factory name="net.sf.saxon.TransformerFactoryImpl"/>
</xslt>

The above example:

  • Changes the <classpath> so it points to just the Saxon JAR file.
  • Adds a <factory> element.

Upvotes: 0

Related Questions