Search code examples
xmlxpathxformsxsltforms

XSLTForms calculation not working when referencing data held in attributes


Apologies if the following question isn't worded well, my experience with all the correct terms in XML is limited.

So I have been using XSLTForms recently as a way to quickly generate xml representations of test data to go into my workplaces LIMS system. However, due to the way the xml must be formed I seem to have hit a snag with XSLTForms or the XPath syntax I am using.

Simplifying my xml format to make a small working example the xhtml file is as follows:

<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
    <title>Example Test</title>
    <xf:model>
        <xf:instance>
            <root xmlns="">
                <child name="one" value=""></child>
                <child name="two" value=""></child>
                <child name="three" value=""></child>
            </root>
        </xf:instance>
        <xf:bind id="ChildOne" ref="child[@name='one']" type="xs:decimal" />
        <xf:bind id="ChildTwo" ref="child[@name='two']" type="xs:decimal" />
        <xf:bind id="ChildThree" ref="child[@name='three']" calculate="../child[@name='one'] - ../child[@name='two']"
            type="xs:decimal" />
    </xf:model>
</head>
<body>
    <xf:input bind="ChildOne">
        <xf:label>Node One:</xf:label>
    </xf:input>
    <xf:input bind="ChildTwo">
        <xf:label>Node Two:</xf:label>
    </xf:input>
    <xf:output ref="child[@name='three']">
        <xf:label>Node Three Calculation:</xf:label>
    </xf:output>
</body>
</html>

This works correctly the inputs are stored in the relevant nodes, the calculate attribute in the final bind tag works out the difference of ChildOne and ChildTwo which is stored in ChildThree. Finally, the output tag displays the value of the ChildThree node.

The calculate attribute in bind works fine when the values in the Xpath expression are stored between the opening and closing Child nodes e.g.:

<child name="ChildOne" value="">10</child>

But as I mentioned at the start, the xhtml code is for a working example, things break when I begin to adapt the code to match the LIMS system's XML structure.

If I change my binds to refer to the value attribute of the Child nodes using @value:

    <xf:bind id="ChildOne" ref="child[@name='one']/@value" type="xs:decimal" />
    <xf:bind id="ChildTwo" ref="child[@name='two']/@value" type="xs:decimal" />
    <xf:bind id="ChildThree" ref="child[@name='three']/@value" calculate="../child[@name='one']/@value - ../child[@name='two']/@value"
        type="xs:decimal" />

Also updating the output ref attribute as follows:

<xf:output ref="child[@name='three']/@value">
    <xf:label>Node Three Calculation:</xf:label>
</xf:output>

The assignment to the value attribute seems to work for ChildOne and ChildTwo which are bound to the input tags. This is confirmed from my working code xml outputs, but the calculate fails to work with only zero being stored within the value attribute.

Am I missing something in the calculate attribute XPath expression?

calculate="../child[@name='one']/@value - ../child[@name='two']/@value"

Any help would be much appreciated, thank you in advance.


Solution

  • When adding "/@value" in bind/@ref, the calculate MIP has to be modified accordingly : calculate="../../child[@name='one']/@value - ../../child[@name='two']/@value