Mule Dataweave script for retrieving attributes in Xml - mule

My Input Xml looks like below
<?xml version="1.0" encoding="UTF-8"?>
<elements>
<element>
<id>123</id>
<items>
<item>
<attributes>
<attribute attribute-id="test1">attr1</attribute>
<attribute attribute-id="test2">attr2</attribute>
</attributes>
</item>
</items>
</element>
</elements>
I tried with below Dataweave script:
%dw 1.0
%output application/xml
---
{
elements: { (payload.elements.*element map {
element: {
test1 : $.items.item.attributes.attribute when $.items.item.attributes.attribute.#attribute-id == 'test1' otherwise '',
test2 : $.items.item.attributes.attribute when $.items.item.attributes.attribute.#attribute-id == 'test2' otherwise ''
}
}
)
}
}
Expected output:
<?xml version='1.0' encoding='windows-1252'?>
<elements>
<element>
<test1>attr1</test1>
<test2>attr2</test2>
</element>
</elements>
Actual output:
<?xml version='1.0' encoding='windows-1252'?>
<elements>
<element>
<test1>attr1</test1>
<test2></test2>
</element>
</elements>
What changes are needed in my data weave script to get the expected output?

Try this
%dw 1.0
%output application/xml
---
{
elements: { (payload.elements.*element map {
element: {($.items.item.attributes.*attribute map {
($.#attribute-id) : $
})}
}
)
}
Yours is not working as there are multiple items.item.attributes.attribute
Hope this helps.

Check the below script
%dw 1.0
%output application/xml
---
{
elements: {
(payload.elements.*element map {
element: {
($.items.item.attributes.*attribute map ((element, index) -> {
(element.#attribute-id) : element when element.#attribute-id == "test1" or element.#attribute-id == "test2"
otherwise ''
}))
}
}
)
}
}
It checks the attribute-id for "test1 and test2", if different sets the value as empty.

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>

XSL - Sum of computed amounts with comparison

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.

variable to custom component - flex

I'm trying to pass a variable from my main flex application to a custom component I've created, but haven't really figured anything out.
my variable is just a string - public var test:String = "a test";
my custom component is implement in my main application like this - <ns1:finaltest includeIn="FinalTest" x="26" y="19" />
In my custom component 'finaltest' I'd like just to display the variable 'test'. something like this - finalmessage.text = test;
MainApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600" xmlns:local="*"
>
<fx:Script>
<![CDATA[
[Bindable]
public var test:String = "a test";
]]>
</fx:Script>
<local:FinalTest finalMessage="{test}" />
</s:Application>
FinalTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="400" height="300"
>
<fx:Script>
<![CDATA[
[Bindable]
public var finalMessage:String;
]]>
</fx:Script>
<s:Label text="{finalMessage}" />
</s:Group>

Flex, States and inheritance

Is it possible to have a child class which adds states to the set of states which are defined in the base class? Currently it looks like my child class overrides all of the states in the base class.
In your child component, create a separate array of states declaratively and in the preinitialize event concatenate them. See this example.
<!-- MyParent -->
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import mx.controls.Button;
private function onCreationComplete():void {
for each(var state:State in states) {
var button:Button = new Button();
button.label = state.name;
button.addEventListener(MouseEvent.CLICK, onClick);
addChild(button);
}
}
private function onClick(event:MouseEvent):void {
currentState = Button(event.target).label;
}
]]>
</mx:Script>
<mx:states>
<mx:State name="Red">
<mx:SetStyle name="backgroundColor" value="#FF0000" />
</mx:State>
<mx:State name="Green">
<mx:SetStyle name="backgroundColor" value="#00FF00" />
</mx:State>
<mx:State name="Blue">
<mx:SetStyle name="backgroundColor" value="#0000FF" />
</mx:State>
</mx:states>
</mx:VBox>
<!-- MyChild -->
<?xml version="1.0" encoding="utf-8"?>
<MyParent xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" preinitialize="onPreinitialize()">
<mx:Script>
<![CDATA[
private function onPreinitialize():void {
states = states.concat(newStates);
}
]]>
</mx:Script>
<mx:Array id="newStates">
<mx:State name="Cyan">
<mx:SetStyle name="backgroundColor" value="#00FFFF" />
</mx:State>
<mx:State name="Purple">
<mx:SetStyle name="backgroundColor" value="#FF00FF" />
</mx:State>
</mx:Array>
</MyParent>
<!-- MyApp -->
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
minWidth="955"
minHeight="600" xmlns="*">
<MyParent width="50%" height="100%" />
<MyChild width="50%" height="100%" right="0" />
</mx:Application>

How can I change (from JavaScript) the title of a XUL window?

In a xulrunner app, I seem to be unable to set the title from JavaScript. I have tried setting in these two ways:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="mywindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="go();">
<!-- your code here -->
<script type="application/x-javascript">
<![CDATA[
function go(){
document.getElementById("mywindow").title="blar";
document.getElementById("mywindow").setAttribute("title","blar");
}
]]>
</script>
</window>
DOM Inspector shows that the title attribute does get updated, but it does not show up on screen.
[CDATA[
function entry_onLoad()
{
document.title = "MyTitle"
}
addEventListener("load", entry_onLoad, false)
]]>
This works
It appears that after the page loads one cannot change the window. If there is a way, I'd be interested to know it.. but this does work:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="mywindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
<script type="application/x-javascript">
<![CDATA[
function go(){
document.getElementById("mywindow").title="blar";
}
go();
]]>
</script>
</window>