Grokbase Groups Ant user March 2016
FAQ
Hello,

I'm facing a weird problem (IMHO) which, in short, is:

a node list passed as a parameter to a template can't be sorted.

The problem occurs only if I do the transformation from within Ant (I use Ant 1.8.4). It does not occur if I perform it via a Java program or in XmlSpy or through http://xsltransform.net.

Here's an example.

The input file (a.xml) is:

<root>
     <a>BBB</a>
     <a>AAA</a>
</root>

The transformation (trans.xml) is:

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" />

   <xsl:template match="/">
     <Root>
       <xsl:call-template name="processThis">
         <xsl:with-param name="nodeList" select="/*/a"/>
       </xsl:call-template>
     </Root>
   </xsl:template>

   <xsl:template name="processThis">
     <xsl:param name="nodeList" />

       <xsl:for-each select="$nodeList">
         <xsl:sort /><!-- ***** This causes the problem -->
         <xsl:variable name="thisVal" select="." />
         <result value="{$thisVal}" />
       </xsl:for-each>
     </xsl:template>

</xsl:stylesheet>

The Ant script is:

<project default="trans">

     <target name="trans">
         <delete file="out.xml"/>
         <xslt style="trans.xsl" in="a.xml" out="out.xml"/>
     </target>

</project>


The expected output is:

<Root>
     <result value="AAA" />
     <result value="BBB" />
</Root>

But if I run the ant script, just an empty 'Root' element is generated, without child nodes.

If I comment out the line marked with '*****', the generated Root element does contain child elements, but unsorted (as one would expect in this case).

If I process the elements directly (and not in a template passing the list to process as a parameter), then I can use 'sort', and everything works as expected. Here is the 'direct' transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

     <xsl:output method="xml" />

     <xsl:template match="/">
         <Root>
             <xsl:for-each select="/*/a">
                 <xsl:sort />
                 <xsl:variable name="thisVal" select="." />
                 <result value="{$thisVal}" />
             </xsl:for-each>
         </Root>
     </xsl:template>

</xsl:stylesheet>

So my question is: why isn't a list passed as a parameter to a template processed with a 'sort' option -- in Ant?

Thank you!
AL

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

Search Discussions

  • Al Le at Mar 7, 2016 at 11:01 am
    It does not occur if I perform it via a Java program
    I have to correct myself. It tried a java program in different JVMs, and it gives me different results. In one case it gives the correct result, in other cases still the wrong result is delivered. I could not find out yet what the difference is.

    But it's not necessarily related to Ant.

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
    For additional commands, e-mail: user-help@ant.apache.org
  • Klaus Malorny at Mar 7, 2016 at 1:26 pm

    On 07.03.2016 12:01, Al Le wrote:
    It does not occur if I perform it via a Java program
    I have to correct myself. It tried a java program in different JVMs, and it
    gives me different results. In one case it gives the correct result, in other
    cases still the wrong result is delivered. I could not find out yet what the
    difference is.
    Hi,

    a quick look into the lib directory of my ANT installation indicates that ANT
    does not come with an own XSL/T implementation, but uses the one provided by the
    JVM. So I would check whether the JVM is the latest available and/or whether
    other included tasks may introduce another XSL/T implementation, which is then
    used by default.

    Klaus



    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
    For additional commands, e-mail: user-help@ant.apache.org
  • Scot P. Floess at Mar 7, 2016 at 11:54 am
    So a few things - first you are killing yourself in the way you XSLT is
    written. Personally, I'd do:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

          <xsl:output method="xml" />

          <xsl:template match="/">
              <Root>
                  <xsl:apply-templates select="a">
                      <xsl:sort select="a"/>
                  </xsl:apply-templates>
              </Root>
          </xsl:template>

          <xsl:template name="a">
              <result>
                  <xsl:attribute name="value">
                      <xsl:value-of select="."/>
                  </xsl:attribute>
              </result>
          </xsl:template>
    </xsl:stylesheet>

    The sort above may be wrong as I didn't test it - but you get the idea.

    You are trying to do the work of the templating engine in your XSLT :)

    See if this works and holler at me if you still can't get it working from
    Ant...

    On Mon, 7 Mar 2016, Al Le wrote:

    Hello,

    I'm facing a weird problem (IMHO) which, in short, is:

    a node list passed as a parameter to a template can't be sorted.

    The problem occurs only if I do the transformation from within Ant (I use Ant 1.8.4). It does not occur if I perform it via a Java program or in XmlSpy or through http://xsltransform.net.

    Here's an example.

    The input file (a.xml) is:

    <root>
    <a>BBB</a>
    <a>AAA</a>
    </root>

    The transformation (trans.xml) is:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" />

    <xsl:template match="/">
    <Root>
    <xsl:call-template name="processThis">
    <xsl:with-param name="nodeList" select="/*/a"/>
    </xsl:call-template>
    </Root>
    </xsl:template>

    <xsl:template name="processThis">
    <xsl:param name="nodeList" />

    <xsl:for-each select="$nodeList">
    <xsl:sort /><!-- ***** This causes the problem -->
    <xsl:variable name="thisVal" select="." />
    <result value="{$thisVal}" />
    </xsl:for-each>
    </xsl:template>

    </xsl:stylesheet>

    The Ant script is:

    <project default="trans">

    <target name="trans">
    <delete file="out.xml"/>
    <xslt style="trans.xsl" in="a.xml" out="out.xml"/>
    </target>

    </project>


    The expected output is:

    <Root>
    <result value="AAA" />
    <result value="BBB" />
    </Root>

    But if I run the ant script, just an empty 'Root' element is generated, without child nodes.

    If I comment out the line marked with '*****', the generated Root element does contain child elements, but unsorted (as one would expect in this case).

    If I process the elements directly (and not in a template passing the list to process as a parameter), then I can use 'sort', and everything works as expected. Here is the 'direct' transformation:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" />

    <xsl:template match="/">
    <Root>
    <xsl:for-each select="/*/a">
    <xsl:sort />
    <xsl:variable name="thisVal" select="." />
    <result value="{$thisVal}" />
    </xsl:for-each>
    </Root>
    </xsl:template>

    </xsl:stylesheet>

    So my question is: why isn't a list passed as a parameter to a template processed with a 'sort' option -- in Ant?

    Thank you!
    AL

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
    For additional commands, e-mail: user-help@ant.apache.org
    Scot P. Floess RHCT (Certificate Number 605010084735240)
    Chief Architect FlossWare http://sourceforge.net/projects/flossware
                                 http://flossware.sourceforge.net
                                 https://github.com/organizations/FlossWare

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
    For additional commands, e-mail: user-help@ant.apache.org
  • Al Le at Mar 7, 2016 at 12:57 pm
    Hello Scot,

    thanks for a quick response!
    first you are killing yourself in the way you XSLT is
    written
    [. . .]
    You are trying to do the work of the templating engine in your XSLT :)
    Yes, I know this is a "procedural" way of doing things and maybe not the best. But the example is just an example. The real script is much bigger and more complicated. I just tried to give a simple case to reproduce the problem.

    Do you also think that it should work (despite the fact that it's may be not the best way to do it)?

    The java program I used to verify the transformation is:

    package my.test;

    import java.io.File;
    import java.io.StringWriter;

    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;

    public class Transform {

      public static void main(String[] args) throws Exception {
       String inputFileName = "Q:\\MiscThings\\t\\a.xml";
       String xslFileName = "Q:\\MiscThings\\t\\trans.xsl";

       Source xmlSource = new StreamSource(new File(inputFileName));
       Source xslSource = new StreamSource(new File(xslFileName));

       StringWriter stringWriter = new StringWriter();
       Result transformationResult = new StreamResult(stringWriter);

       TransformerFactory transformerFactory = TransformerFactory.newInstance();
       Transformer transformer = transformerFactory.newTransformer(xslSource);
       transformer.transform(xmlSource, transformationResult);

       stringWriter.flush();
       String xmlResult = stringWriter.toString();

       System.out.println(xmlResult);
      }

    }

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
    For additional commands, e-mail: user-help@ant.apache.org
  • Sfloess at Mar 7, 2016 at 1:55 pm
    Al,

    It wasn't apparent to me why there'd be a difference...

    If you are using the same JVM and simply executing the XSL differently, I don't see why not...

    I mean once you kick of the XSL I can't imagine there is something different in running from Ant vs your Java app. I spent a number of years on an ESB team doing mostly XSLTs (and XSDs) - I always used Ant to test even though we ran the XSLTs in our environments from Java. I never noticed any difference that way at all.


    ---- Al Le wrote:
    Hello Scot,

    thanks for a quick response!
    first you are killing yourself in the way you XSLT is
    written
    [. . .]
    You are trying to do the work of the templating engine in your XSLT :)
    Yes, I know this is a "procedural" way of doing things and maybe not the best. But the example is just an example. The real script is much bigger and more complicated. I just tried to give a simple case to reproduce the problem.

    Do you also think that it should work (despite the fact that it's may be not the best way to do it)?

    The java program I used to verify the transformation is:

    package my.test;

    import java.io.File;
    import java.io.StringWriter;

    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;

    public class Transform {

    public static void main(String[] args) throws Exception {
    String inputFileName = "Q:\\MiscThings\\t\\a.xml";
    String xslFileName = "Q:\\MiscThings\\t\\trans.xsl";

    Source xmlSource = new StreamSource(new File(inputFileName));
    Source xslSource = new StreamSource(new File(xslFileName));

    StringWriter stringWriter = new StringWriter();
    Result transformationResult = new StreamResult(stringWriter);

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer(xslSource);
    transformer.transform(xmlSource, transformationResult);

    stringWriter.flush();
    String xmlResult = stringWriter.toString();

    System.out.println(xmlResult);
    }

    }

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

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
    For additional commands, e-mail: user-help@ant.apache.org
  • Earl Hood at Mar 7, 2016 at 5:18 pm

    On Mar 7, 2016 7:55 AM, wrote:
    If you are using the same JVM and simply executing the XSL differently, I
    don't see why not...

    If the classpath is not identical, you could get a different transform
    provider. For example, we use Saxon as our provider, overriding what is
    provided in the runtime library.

    Wrt Ant, we put Saxon in its lib path so we know it will get used since we
    have other programs outside of Ant invocation context that use Saxon.
    Puting it in the lib path avoids the need to explicitly designate the
    provider in the xslt task.

    --ewh
  • Al Le at Mar 7, 2016 at 10:00 pm

    If the classpath is not identical, you could get a different transform
    provider. For example, we use Saxon as our provider, overriding what is
    provided in the runtime library.

    Thank you for the hint! I downloaded the latest xalan distribution and
    executed the ant script with the "classpath" attribute pointing to xalan.

    And it worked! I naively assumed that a modern Java distributions (Java
    8) include an xslt processor good enough to carry out this simple
    transformation correctly. But it's apparently not the case.

    So, when in doubt, specify the xslt processor explicitly and do not rely
    on the one contained in the JDK!

    Thank you all who has responded! Now the world is half sane again (only
    half because JDK contains a flawed xslt processor).

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

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriesant
postedMar 7, '16 at 6:37a
activeMar 7, '16 at 10:00p
posts8
users4
websiteant.apache.org

People

Translate

site design / logo © 2018 Grokbase