XSL - Sum of computed amounts with comparison - sum

I need some help to compute sum and add some comparison complexity to know which element should be part of the sum.
Let's take the following XML
<REF>
<amount>3</amount>
<rate>7</rate>
</REF>
<A>
<amount>10</amount>
<rate>4</rate>
</A>
<A>
<amount>-21</amount>
<rate>2</rate>
</A>
<B>
<amount>8</amount>
<rate>1</rate>
</B>
<C>
<amount>7</amount>
<rate>32</rate>
</C>
I would like to display the sum of each amount multiplied by each associated rate within a Total element.
And I would like to split my total into two elements: NegativeTotal and PositiveTotal.
PostiveTotal will contain the SUM of ((amount * rate) if the value is greater than (amount * rate) of REF object)
NegativeTotal will contain the SUM of ((amount * rate) if the value is less than (amount * rate) of REF object)
It should give the below output
<Total>
<PositiveTotal>
264 <!-- 40 + 224 -->
</PositiveTotal>
<NegativeTotal>
-34 <!-- -42 + 8 -->
</NegativeTotal>
</Total>
Please let me know if it's possible
For information technical limitation: XSLT 1.0
Thanks in advance
Regards,

I would suggest you do it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<!-- first pass -->
<xsl:variable name="summands-rtf">
<xsl:for-each select="*">
<value>
<xsl:value-of select="amount * rate" />
</value>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="summands" select="exsl:node-set($summands-rtf)/value" />
<!-- get the threshold -->
<xsl:variable name="threshold" select="REF/amount * REF/rate" />
<!-- output -->
<Total>
<PositiveTotal>
<xsl:value-of select="sum($summands[. > $threshold])" />
</PositiveTotal>
<NegativeTotal>
<xsl:value-of select="sum($summands[. < $threshold])" />
</NegativeTotal>
</Total>
</xsl:template>
</xsl:stylesheet>
When applied to a well-formed XML input (with a single root element):
XML
<root>
<REF>
<amount>3</amount>
<rate>7</rate>
</REF>
<A>
<amount>10</amount>
<rate>4</rate>
</A>
<A>
<amount>-21</amount>
<rate>2</rate>
</A>
<B>
<amount>8</amount>
<rate>1</rate>
</B>
<C>
<amount>7</amount>
<rate>32</rate>
</C>
</root>
the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<Total>
<PositiveTotal>264</PositiveTotal>
<NegativeTotal>-34</NegativeTotal>
</Total>
Note that the product of REF amount and rate is not included in any of the two totals, as it is neither above nor below the threshold. Similarly, if any other product happens to be equal to the threshold. it too will be excluded.

Related

Grouping list of dates by year, using XSLT 1.0

Could you help me? I have XML:
<root>
<prop>
<holidays>2011-01-01</holidays>
<holidays>2011-01-02</holidays>
...
<holidays>2012-01-01</holidays>
<holidays>2012-01-02</holidays>
...
</prop>
</root>
I need to get the following JSON from it:
[
{
"id" : "2011",
"data" :
[
"2011-01-01","2011-01-02" ...
]
},
{
"id" : "2012",
"data" :
[
"2012-01-01","2012-01-02" ...
]
},
...
]
With XSLT transformation 1.0
Thank you in Advance for your help!
UPDATE: Here is a solution that suited me
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" exclude-result-prefixes="xsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="text"/>
<xsl:key name="group" match="prop/holidays" use="substring-before(string(.),'-')"/>
<xsl:template match="root">[
<xsl:apply-templates select="prop/holidays[generate-id(.) = generate-id(key('group',substring-before(string(.),'-')))]" />]</xsl:template>
<xsl:template match="holidays">{
"id" : "<xsl:value-of select="substring-before(string(.),'-')"/>",
"data" :
[
<xsl:for-each select="key('group',substring-before(string(.),'-'))">"<xsl:value-of select="."/>",</xsl:for-each>
]
},
</xsl:template>
</xsl:stylesheet>

Xamarin Forms - Html2Xaml converter issue with span TapGestureRecognizer command

I'm trying to convert custom html text in FormattedString xaml for any label. There, I have an <a/> tag where it will convert to an span with TapGestureRecognizer:
<xsl:template match="A | a" priority="9">
<Span TextDecorations="Underline">
<xsl:attribute name="Text">
<xsl:apply-templates />
</xsl:attribute>
<Span.GestureRecognizers>
<TapGestureRecognizer Command="{{Binding PopupContentCommand}}">
<xsl:attribute name="CommandParameter">
<xsl:value-of select="#href" />
</xsl:attribute>
</TapGestureRecognizer>
</Span.GestureRecognizers>
</Span>
</xsl:template>
The converter is working well, the issue is that this command binding is not raising. When we load new FormattedString().LoadFromXaml(xaml) the converted html to xaml, the command appears to have binding:
But this binding is not raising. After that I try to Clear the GestureRecognizers and create an new TapGestureRecognizer adding it again. But this didn't work neither. The BindingContext appears to be the correct one too.
This is done by binding an attached property:
<Label attachedProperties:Properties.Html="{Binding HtmlText}" />
Finally it was a simulator issue. Because in the real devices this raise without problem.

XSL - Check if select has no text nodes then show "Not Results"

How can I check if my block/select has no text nodes then show "Not Results"
<xsl:choose>
<xsl:when test="#pass='0' or #pass='1'">
<fo:block padding-top="1cm" font-weight="bold" margin-bottom="0.2cm">Header</fo:block> <fo:block margin-top="0.2cm" margin-bottom="0.2cm" border-bottom="1px solid #e1e1e1">
</fo:block>
<fo:block margin-top="0.2cm" margin-bottom="0.2cm" padding-left="5px" padding-right="5px" padding-top="1px">
<xsl:apply-templates select="detail/katalog/frage[#ko='1' and #passed='0']" />
<xsl:apply-templates select="detail/katalog/frage/options" />
<xsl:apply-templates select="detail/katalog/matrix/frage/options" />
<xsl:apply-templates select="detail/katalog/clusterArea/clusterFrage[#ko='1' and #passed='0']" />
</fo:block>
I tried this, but it doesn't work.
<xsl:if test="(not(detail/katalog/frage[#ko='1' and #passed='0']) and not(detail/katalog/clusterArea/clusterFrage[#ko='1' and #passed='0']) and not(detail/katalog/frage/options) and not(detail/katalog/matrix/frage/options))">
<fo:block>
Not Results
</fo:block>
</xsl:if>
Thanks a lot!
PR
If the elements you are checking exist, but your current check detail/katalog/frage[#ko='1' and #passed='0'] for example will return true, as that is just checking for the existence of the element itself, regardless of whether it has child nodes or not
So, you want to do something like this....
not(detail/katalog/frage[#ko='1' and #passed='0']/text())
However, you also need to watch out for whitespace only nodes, so you might want to augment the check like so...
not(detail/katalog/frage[#ko='1' and #passed='0']/text()[normalize-space()])
Alternatively, you could strip out whitespace only nodes by using xsl:strip-space
<xsl:strip-space elements="*" />

Need to parse repeatedly (loop) over the same piece of XML using NSXMLParser

I have a string of XML that I'd like to use to describe a table layout. Sort of like a template. I'm using NSXMLParser to parse this.
<section title="section a">
<row label="name" property="fullname" />
<row label="gender" property="gender" />
</section>
<section title="section b">
<row label="pet" property="pet" />
</section>
<repeat foreach="companies">
<section title="name">
<row label="address" property="address" />
<row label="email" property="email" />
</section>
</repeat>
As for the part between the <repeat> tags, I intent to loop over this part 0 to n times for each of the entries in an array. The NSXMLParser however doesn't seem to have an easy way of doing this. I see no option to jump back to a previous line. The only way I can think of is storing everything between the <repeat> tags in a variable and doing my custom parsing and repeating of it in the parser:didEndElement:... method. I wonder though, isn't there a better way to do this maybe?

gridpane resize

I want a gridpane layout as in the attached image. Anyone know how to this or am I using the wrong layout?
You can control how different rows and columns in a GridPane grow using column and row constraints.
The way to do this is to set the hgrow property of the first column to ALWAYS, and the vgrow property of the first row to ALWAYS - this means the top left cell will always expand. You can either set the other cells to fixed widths/heights, or otherwise they will expand to fit their contents and no more.
I've included an FXML example with the GridPane inside an AnchorPane, and anchored to the top, left bottom and right of the AnchorPane. This means that the GridPane will grow to fill the parent AnchorPane:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
<children>
<GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" />
<ColumnConstraints prefWidth="150" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="ALWAYS" />
<RowConstraints prefHeight="150" />
</rowConstraints>
</GridPane>
</children>
</AnchorPane>
This results in the layout shown here, and expands to fill the parent pane:
Turns out what I am trying to do requires AnchorPane and GridPane.