Re: [xsl] Instance construction and use of a java.util.ArrayList

Subject: Re: [xsl] Instance construction and use of a java.util.ArrayList
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Fri, 17 Aug 2012 23:04:07 +0100
In Saxon, if you don't use a variable then its initializer is never evaluated. So declaring a variable in the hope that its initializer will cause side-effects is not a good strategy.

Using xsl:value-of to evaluate the side-effecting method is better, but of course it gives you a problem when the method (as here) returns a result. The way to deal with this is to filter away the result with a predicate that always returns false, for example

<xsl:value-of select="ArrayList.add(...)[string(.)='never']"/>

Product-specific questions are best asked on a forum specific to that product. For Saxon, please use the forums at dev.saxonica.com.

Michael Kay
Saxonica


On 17/08/2012 16:02, Roger Martin wrote:
Hi,

I'm using saxonb9-1-0-8j with jdk1.7.0_05 on Unbuntu 12.04 (64 bit) and Windows 7 (Home Premium 64 bit)

Attempting to use a java.util.ArrayList for going to another class needing a Java array. But first:

...in namespace area...
xmlns:KabschAlignment="java:org.openscience.cdk.geometry.alignment.KabschAlignment"
                 xmlns:cdkatom="java:org.openscience.cdk.Atom"
                 xmlns:Point3d="java:javax.vecmath.Point3d"
                 xmlns:ArrayList="java:java.util.ArrayList"
                 xmlns:date="java:java.util.Date"
.......
further along

.......
<xsl:variable name="primary-atom-list" select="ArrayList:new()"/>
<xsl:for-each select="./cml:molecule/cml:molecule/cml:atomArray/*">
<xsl:variable name="add" select="ArrayList:add($primary-atom-list, cdkatom:new(@elementType, Point3d:new(@x3, @y3, @z3)))"/>
</xsl:for-each>
<xsl:comment>
<xsl:text> primary atoms: </xsl:text>
<xsl:value-of select="$number-of-atoms"/>
<xsl:text> size: </xsl:text>
<xsl:value-of select="ArrayList:size($primary-atom-list)"/>
</xsl:comment>
.......
the size as printed in the comment is zero. I've tried simpler content for ArrayList and same zero. Also if the


....
<xsl:variable name="add" select="ArrayList:add($primary-atom-list, cdkatom:new(@elementType, Point3d:new(@x3, @y3, @z3)))"/>
....
is changed to


....
<xsl:value-of select="ArrayList:add($primary-atom-list, cdkatom:new(@elementType, Point3d:new(@x3, @y3, @z3)))"/>
....
a bunch of truetruetrue's arrive in output.


......
<xsl:variable name="primary-atom-list" select="ArrayList:new()"/>
<xsl:for-each select="./cml:molecule/cml:molecule/cml:atomArray/*">
<xsl:variable name="add" select="ArrayList:add($primary-atom-list, 'test with string')"/>
</xsl:for-each>
<xsl:comment>
<xsl:text> primary atoms: </xsl:text>
<xsl:value-of select="$number-of-atoms"/>
<xsl:text> size: </xsl:text>
<xsl:value-of select="ArrayList:size($primary-atom-list)"/>
</xsl:comment>
.......
leads to zero size as well. Tried a few add's in a row instead of the for-each loop and got zero size too.


Compiles and runs just fine. No errors or exceptions. The rest of the xsl works and completes.

Any ideas? Do I need to make a custom class to do the work?

The idea is to send two atom arrays into the KabschAlignment (which is a big algorithm not fitting xsl readily) to check for rmsd match of two chemicals or not:

--------
.<?xml version="1.0"?>
<!-- Collates nmr values to the starting chemical definition by selecting comparable candidate from the nmr cml document.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:xlink="http://www.w3.org/1999/xlink";
xmlns:divcon="http://quantumbioinc.com/schema/divcon";
xmlns:molecularmechanics="http://quantumbioinc.com/schema/molecularmechanics";
xmlns:cml="http://www.xml-cml.org/schema/cml2/core";
xmlns:ocml="http://www.xml-cml.org/schema";
xmlns:functx="http://www.functx.com";
xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns:saxon="http://saxon.sf.net";
xmlns:KabschAlignment="java:org.openscience.cdk.geometry.alignment.KabschAlignment"
xmlns:cdkatom="java:org.openscience.cdk.Atom"
xmlns:Point3d="java:javax.vecmath.Point3d"
xmlns:ArrayList="java:java.util.ArrayList"
xmlns:date="java:java.util.Date"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xsi:schemaLocation="http://quantumbioinc.com/schema/divcon ../schemas/divcon.xsd"
version="2.0" extension-element-prefixes="saxon">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<!--xsl:strip-space elements="*"/-->
<xsl:param name="file-path" select="."/>


<xsl:function name="functx:is-value-in-sequence" as="xs:boolean"
              xmlns:functx="http://www.functx.com"; >
<xsl:param name="value" as="xs:anyAtomicType?"/>
<xsl:param name="seq" as="xs:anyAtomicType*"/>

<xsl:sequence select="
   $value = $seq
 "/>

</xsl:function>

<xsl:template match="/">
<xsl:apply-templates select="./divcon:divcon"/>
</xsl:template>

<xsl:template match="divcon:divcon">
<xsl:element name="divcon:divcon" inherit-namespaces="yes">
<xsl:copy-of select="@*"/>
<xsl:namespace name="cml" select="'http://www.xml-cml.org/schema/cml2/core'"/>
<xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
<xsl:copy-of select="./divcon:general-quantum-mechanics"/>
<xsl:copy-of select="./divcon:Hamiltonian"/>
<xsl:copy-of select="./divcon:geometry-optimization"/>
<xsl:copy-of select="./divcon:outputs"/>
<xsl:copy-of select="./divcon:charges"/>
<xsl:copy-of select="./divcon:heat-of-formation"/>
<xsl:copy-of select="./divcon:solvation-free-energy"/>
<xsl:copy-of select="./divcon:ionization-potential"/>
<xsl:copy-of select="./divcon:dipole-moment"/>
<xsl:copy-of select="./divcon:subsettings"/>
<xsl:copy-of select="./divcon:divcon/self-consistent-reaction-field"/>
<xsl:copy-of select="./divcon:divcon/nuclear-magnetic-resonance"/>
<xsl:apply-templates select="./cml:cml"/>
<xsl:apply-templates select="./divcon:benchmark-set"/>
<xsl:apply-templates select="./divcon:experimental-reference-set"/>
<xsl:copy-of select="./divcon:energyArray"/>
<xsl:copy-of select="./divcon:partial-chargeArray"/>
<xsl:copy-of select="./divcon:score-set"/>
<xsl:copy-of select="./divcon:computation-status"/>
</xsl:element>
</xsl:template>


<xsl:template match="cml:cml">
<xsl:variable name="number-of-atoms" select="count(./cml:molecule/cml:molecule/cml:atomArray/*)"/>
<xsl:variable name="primary-atom-list" select="ArrayList:new()"/>
<xsl:for-each select="./cml:molecule/cml:molecule/cml:atomArray/*">
<xsl:variable name="add" select="ArrayList:add($primary-atom-list, cdkatom:new(@elementType, Point3d:new(@x3, @y3, @z3)))"/>
</xsl:for-each>
<xsl:comment>
<xsl:text> primary atoms: </xsl:text>
<xsl:value-of select="$number-of-atoms"/>
<xsl:text> size: </xsl:text>
<xsl:value-of select="ArrayList:size($primary-atom-list)"/>
</xsl:comment>
<xsl:variable name="atom-array" select="document($file-path)/ocml:cml/ocml:molecule/*"/>
<xsl:for-each-group select="$atom-array" group-by="count(./atom) = $number-of-atoms">
<xsl:comment>
<xsl:if test="function-available('date:to-string') and
function-available('date:new')">
<p><xsl:value-of select="date:to-string(date:new())"/></p>
<xsl:text>


</xsl:text>
</xsl:if>
<xsl:value-of select="local-name(.)"/>
<xsl:text>: group </xsl:text>
<xsl:value-of select="count(./*)"/>
<xsl:text> name: </xsl:text>
<xsl:value-of select="name(./*[1])"/>
</xsl:comment>
<xsl:variable name="atom-list" select="ArrayList:new()"/>
<xsl:for-each select="./*">
<xsl:variable name="add" select="ArrayList:add($atom-list, cdkatom:new(@elementType, Point3d:new(@x3, @y3, @z3)))"/>
</xsl:for-each>
<xsl:variable name="kabsch-alignment" select="KabschAlignment:new(ArrayList:to-array($primary-atom-list), ArrayList:to-array($atom-list))"/>
<xsl:variable name="align" select="KabschAlignment:align($kabsch-alignment)"/>
<xsl:variable name="rmsd" select="KabschAlignment:get-RMSD($kabsch-alignment)"/>
<xsl:comment>
<xsl:text> cdk atoms: </xsl:text>
<xsl:value-of select="count($atom-list)"/>
<xsl:text> size: </xsl:text>
<xsl:value-of select="ArrayList:size($atom-list)"/>
<xsl:text> rmsd: </xsl:text>
<xsl:value-of select="$rmsd"/>
</xsl:comment>
</xsl:for-each-group>
</xsl:template>


<xsl:template match="divcon:benchmark-set">
<xsl:element name="divcon:benchmark-set" inherit-namespaces="yes">
<xsl:copy-of select="./divcon:reference-mark"/>
<xsl:copy-of select="./divcon:heat-of-formation"/>
<xsl:copy-of select="./divcon:solvation-free-energy"/>
<xsl:copy-of select="./divcon:ionization-potential"/>
<xsl:copy-of select="./divcon:dipole-moment"/>
</xsl:element>
</xsl:template>

<xsl:template match="divcon:experimental-reference-set">
<xsl:element name="divcon:experimental-reference-set" inherit-namespaces="yes">
<xsl:copy-of select="./divcon:heat-of-formation"/>
<xsl:copy-of select="./divcon:solvation-free-energy"/>
<xsl:copy-of select="./divcon:ionization-potential"/>
<xsl:copy-of select="./divcon:dipole-moment"/>
</xsl:element>
</xsl:template>


</xsl:stylesheet>
-------

Current Thread