I Have a .jtl file which is the output of a jmeter run.
while generating the report, i want to group all samples under one thread if they have a substring "PASS".
Currently am trying the below code:
<xsl:for-each select="/testResults/*[not(#lb = preceding::*/#lb)]">
<xsl:variable name="label" select="substring-before(#lb,'#')" />
</xsl:for-each>
where
lb = PASS#US_Edit_make_year_VehicleName_model
lb = PASS#US_Edit_make_year_VehicleName_year
OutPut should be like:
PASS
->US_Edit_make_year_VehicleName_model
->US_Edit_make_year_VehicleName_year
But it is repeating twice since PASS is repeated twice.
please suggest
<xsl:for-each select="/testResults/*[not(#lb = preceding::*/#lb)]">
<xsl:variable name="label" select="substring-before(#lb,'#')" />
</xsl:for-each>
OutPut should be like
PASS
->US_Edit_make_year_VehicleName_model
->US_Edit_make_year_VehicleName_year
Output Got is:
PASS
->US_Edit_make_year_VehicleName_model
->US_Edit_make_year_VehicleName_year
PASS
->US_Edit_make_year_VehicleName_model
->US_Edit_make_year_VehicleName_year
Related
I am new to XSL.I have an XML as below, If CoverageCode equals -'HomeCoverage' then I have to verify for the next 3 elements of 'roofRestrictionEndt','sidingRestrictionEndt'and 'paintRestrictionEndt' . If 'roofRestrictionEndt' exits and its value is 'Y' then I need to print 'Roof' under the 'results' tag, If 'sidingRestrictionEndt' exists and its value is 'Y' then I need to print 'siding' in case if it exists along with the above one then I need to print 'Roof; siding'. If 'paintRestrictionEndt' exists and its value is 'Y' along with the other 2 elements then I need to print 'Roof; siding; paint'. I tried by declaring variables and wrote If conditions and tried to append values accordingly inside IF condition, but I came to know the declared variables are immutable. In java, we can achieve this by using StringBuffer. Is there any way to achieve this in XSL? Below is XML.
<locationCoverage ID="3">
<coverageCode >HomeCoverage</coverageCode>
<roofRestrictionEndt >Y</roofRestrictionEndt>
<sidingRestrictionEndt>Y</sidingRestrictionEndt>
<paintRestrictionEndt >Y</paintRestrictionEndt>
<locationCoverage>
Results should look like as below
<results>
<result>Roof;siding;paint</result>
</results>
If I have below input XML
<locationCoverage ID="3">
<coverageCode >HomeCoverage</coverageCode>
<roofRestrictionEndt >Y</roofRestrictionEndt>
<paintRestrictionEndt >Y</paintRestrictionEndt>
</locationCoverage>
For the above XML results should look like as below
<results>
<result>Roof;paint</result>
</results>
Appreciate it If anyone helps me with this. Thanks in advance.
If I understand this correctly (which is not at all certain), you want to do something like:
<xsl:template match="locationCoverage[coverageCode='HomeCoverage']">
<xsl:variable name="test-results">
<xsl:if test="roofRestrictionEndt='Y'">Roof </xsl:if>
<xsl:if test="sidingRestrictionEndt='Y'">siding </xsl:if>
<xsl:if test="paintRestrictionEndt='Y'">paint</xsl:if>
</xsl:variable>
<result>
<xsl:value-of select="translate(normalize-space($test-results), ' ', ';')"/>
</result>
</xsl:template>
I'm working on a BizTalk project and I need to get the minimum date between many dates which are in different nodes using BizTalk mapping and XSLT.
I have search for some example and I found this: How to find minimum date from different xml date nodes using xslt which seems relevant with my problem.
So I modified the code and put it in the Scripting functoid under script type "Inline XSLT Call Template" then I built my project and it returns me this error "The number of inputs to the scripting functoid does not match with the number of inputs expected by the xsl:call template."
As I am pretty newbie with XSLT and BizTalk, any help is welcome.
I have already move the link between Input node and functoid but got the same error.
Here is the XSLT Inline script
<xsl:template name="ExtractMinStartDate">
<xsl:for-each select="/*[local-name()='Employee']/*[local-name()='Contracts']/*[local-name()='Contract']/*[local-name()='EmployementStartDate']">
<xsl:sort select="substring(Date,1,4)" data-type="string" order="ascending"/>
<xsl:sort select="substring(Date,6,2)" data-type="string" order="ascending"/>
<xsl:sort select="substring(Date,9,2)" data-type="string" order="ascending"/>
<xsl:if test="position()=1">
<xsl:value-of select="EmployementStartDate" />
</xsl:if>
</xsl:for-each>
</xsl:template>
Here is the xml in input
<Employee xmlns="http://Securitas.ESB.HR.EmployeeUDMToRostar.MDSRequest_Schema">
<Number>157989</Number>
<SagaNumber>23776</SagaNumber>
<SurNameFull>Test</SurNameFull>
<FirstName>test</FirstName>
<GivenName>test</GivenName>
<Gender>Man</Gender>
<DateOfBirth>1992-04-07T00:00:00.0000000+02:00</DateOfBirth>
<EmailPrivate>test#hotmail.com</EmailPrivate>
<PhoneMobilePrivate>5145454558</PhoneMobilePrivate>
<PhonePrivate/>
<EmployementStartDate/>
<EmployementEndDate/>
<UPN/>
<SAMAccountName/>
<Functions>
<Function>
<StartDate>2011-10-10T00:00:00.0000000+02:00</StartDate>
<EndDate>2015-05-31T00:00:00.0000000+02:00</EndDate>
<CostCenter>sdrg gerg jytfjdqert htrh</CostCenter>
<CostCenterCode/>
<Position>ihygkhgkjhgv A</Position>
</Function>
</Functions>
<Contracts>
<Contract>
<ID>ce369e13-f21f-4210-88e5-502bee3cdcc0</ID>
<StartDate>2015-10-10T00:00:00.0000000+02:00</StartDate>
<EndDate/>
<EmployementStartDate>2024-10-10T00:00:00.0000000+02:00</EmployementStartDate>
<EmployementEndDate/>
<Type>Onbepaalde tijd</Type>
<PhaseID>O</PhaseID>
<PB_CAO>true</PB_CAO>
<DissimelarCAO>VPB</DissimelarCAO>
</Contract>
<Contract>
<ID>ce369e13-f21f-4210-88e5-502bee3cdcc0</ID>
<StartDate>2011-10-10T00:00:00.0000000+02:00</StartDate>
<EndDate/>
<EmployementStartDate>2011-10-10T00:00:00.0000000+02:00</EmployementStartDate>
<EmployementEndDate/>
<Type>Onbepaalde tijd</Type>
<PhaseID>O</PhaseID>
<PB_CAO>true</PB_CAO>
<DissimelarCAO>VPB</DissimelarCAO>
</Contract>
</Contracts>
<Roosters>
<Rooster>
<StartDate>2011-10-10T00:00:00.0000000+02:00</StartDate>
<EndDate/>
<WeekAmountOfHours>30.5</WeekAmountOfHours>
</Rooster>
</Roosters>
<Wages>
<Wage>
<ID>c4df91b1-292d-464e-b17f-259968b9c39c</ID>
<StartDate>2016-12-05T00:00:00.0000000+01:00</StartDate>
<EndDate>2017-01-01T00:00:00.0000000+01:00</EndDate>
<HourlyWage>12.74</HourlyWage>
<RightTravelExpense>true</RightTravelExpense>
<RightTravelHours>true</RightTravelHours>
<RightAdditions>true</RightAdditions>
<MaxKm/>
<DissimelarZipCode/>
</Wage>
</Wages>
</Employee>
The result expect in output xml is to get the oldest "EmployementStartDate" so in this case is
<Employee xmlns="http://Securitas.ESB.HR.EmployeeUDMToRostar.MDSRequest_Schema">
<Number>157989</Number>
<SagaNumber>23776</SagaNumber>
<SurNameFull>Test</SurNameFull>
<FirstName>test</FirstName>
<GivenName>test</GivenName>
<Gender>Man</Gender>
<DateOfBirth>1992-04-07T00:00:00.0000000+02:00</DateOfBirth>
<EmailPrivate>test#hotmail.com</EmailPrivate>
<PhoneMobilePrivate>5145454558</PhoneMobilePrivate>
<PhonePrivate/>
<EmployementStartDate>2011-10-10T00:00:00.0000000+02:00</EmployementStartDate>
.
.
.
</Employee>
All,
i am searching in a list of fields those who has the type clob and i am writing it separed by a comma like this [field1, field2, ... fieldn]
my problem is how to identify the first matched field to write it without comma ( i can't use position() because the first field matched can be the first of the list or the last of the list)
I want to make this algorithm in xslt,
variable is_first = TRUE;
if(is_first) {
do smthng;
isfirst = False;
}
Actually it is not possible to make something like this in xslt since variable are immutable. There probably could be workarounds but you have to specify your need in more details.
edit:
If your input is string with values separated by commas...
<xsl:variable name="inputString" select="'field1,field2,field3a,field4,field3b'" />
... you could use tokenize() functions...
<xsl:variable name="tokenized" select="tokenize($inputString, ',')" />
... and then select items corresponding to your condition
<!-- Select item corresponding to condition (e.g. it contains 3). Take first one if there are several such items -->
<xsl:value-of select="$tokenized[contains(., '3')][1]" />
Edit2:
You can use separator attribute of xsl:value-of (xslt 2.0) for output of delimited values.
Assuming following variable
<xsl:variable name="list">
<item>first</item>
<item>second</item>
<item>third</item>
</xsl:variable>
this <xsl:value-of select="$list/item" separator="," /> makes desired output first,second,third
You need to write this using functional code rather than procedural code. It's not possible to do the conversion without seeing the context (it's much easier to work from the problem rather than from the solution in a lower-level language).
But the most common equivalent in XSLT would take the form
<xsl:for-each select=".....">
<xsl:if test="position() = 1"><!-- first time code --></xsl:if>
....
</xsl:for-each>
I'm trying to map two documents witht the BizTalk Mapper and my target document should look like this:
<root>
<complexType>
<property>example</property>
</complexType>
<filler>
<padding>9999999</padding>
</filler>
<filler>
<padding>9999999</padding>
</filler>
<filler>
<padding>9999999</padding>
</filler>
</root>
The number of <filler> nodes that I should create is variable (from 0 to 9). It is basically the result of a calculation (based on some data provided in the source document).
Is there a way to create those <filler> nodes with some combination of functoids?
I tried to use the Table Looping functoid (created a table with only one column, the padding char '9') but doesn't really work because it creates as many <filler> nodes as rows are defined in the table, which is not what I want since the number of rows would have to be variable (again, based on a calculation).
What I currently do is pass the message (XmlDocument) to a C# method and then I programmatically append the <filler> nodes.
I'm hoping that there is a more "BizTalk-y" way of doing this with the Mapper.
I suspect that you will have to solve this problem by altering the XSLT.
Add some logic to create as many filler nodes as the result of your calculation dictates - you could create a template which you call in a loop perhaps, which would append a new filler section.
Hope this points you in the right direction.
As pointed out, XSLT can create nodes on the target document at will (I didn't know this and this was the key part).
Turns out that what I needed is a simple for-loop in XSLT. Once I realized this, a quick Google search yielded the following results:
http://quomon.com/question-How-to-make-a-for-loop-in-xslt-not-for-each-809.aspx
http://snippets.dzone.com/posts/show/930
Another thing worth noting is that (as pointed out by the first link), XSLT is a functional language, not procedural, so sometimes you do have to resort to using recursion or an extension.
This case is definitely one of those times since I couldn't use a careful selection of nodes using the select attribute on an xsl:for-each (since this filler data wasn't part of the source document).
Specifically, for this case, what I did was:
Add a Scripting functoid.
Add two inputs:
A constant with value "1" (this is the initial value of the i variable)
The length of the loop (number of times to repeat the body of the loop)
Paste the following XSLT template as an "Inline XSLT Call Template" script:
<xsl:template name="ForLoop">
<xsl:param name="i" /> <!-- index counter, 1-based, will be incremented with every recursive call -->
<xsl:param name="length" /> <!-- exit loop when i >= length -->
<!-- Output the desired node(s) if we're still looping -->
<!-- The base case is when i > length (in that case, do nothing) -->
<xsl:if test="$i <= $length">
<Filler>
<Padding>999999</Padding>
</Filler>
</xsl:if>
<!-- Call the ForLoop template recursively, incrementing i -->
<xsl:if test="$i <= $length">
<xsl:call-template name="ForLoop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="length">
<xsl:value-of select="$length"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
I'm receiving XML into BizTalk. One part is element and the value is ids separated by comma
<Stores>15,34</Stores>
I need to transform this into
<Stores>
<Store>Store 1</Store>
<Store>Store 4</Store>
</Stores>
What I need to do is to explode the value by comma, take each value and get value from database (15 -> Store 1, 34 -> Store 2).
How can I make the explode in xslt, how ca I get value from database for each exploded value. I already have procedure in db for that, just need to know how to call it.
Here is an XSLT 1.0 compatible solution that does the explode:
<!-- straightforward -->
<xsl:template match="Stores">
<xsl:copy>
<xsl:call-template name="explode">
<xsl:with-param name="str" select="text()" />
</xsl:call-template>
</xsl:copy>
</xsl:template>
<!-- string processing through recursion -->
<xsl:template name="explode">
<xsl:param name="str" select="''" />
<xsl:variable name="temp" select="concat($str, ',')" />
<xsl:variable name="head" select="substring-before($temp, ',')" />
<xsl:variable name="tail" select="substring-after($temp, ',')" />
<xsl:if test="$head != ''">
<Store>
<xsl:value-of select="$head" />
</Store>
<xsl:call-template name="explode">
<xsl:with-param name="str" select="$tail" />
</xsl:call-template>
</xsl:if>
</xsl:template>
Output for <Stores>15,34</Stores> would be:
<Stores>
<Store>Store 15</Store>
<Store>Store 34</Store>
</Stores>
David Hall's solution seems to contain a pointer how to use an XSLT extension function to make calls to that database from XSLT.
The BizTalk Mapper does not support XSLT 2.0 (see MSDN Documentation http://msdn.microsoft.com/en-us/library/aa559261(BTS.10).aspx) so you will need to use the EXSLT extensions if you want to use the mapper.
There is a great post here by Richard Hallgren that covers how to use EXSLT within the BizTalk Mapper.
One additional thought is about an alternative solution. It is not clear if you absolutely must make your database calls one by one - would making a single call work?
It is possible to provide a stored procedure a delimited string as a parameter and to then use a function to break this string up. I've included an example of such a function below, the example being a table function. You'll be able find lots of other implementations on the web.
With the table function you can join against this in you store lookup procedure.
If this meets your needs it should be a lot faster since you now perform just a single database hit and can perform set operations to get back your list of stores.
CREATE function fn_ParseCSVString
(
#INPUTCSV varchar(MAX)
)
RETURNS #TBL TABLE
(
COL1 INT
)
AS
BEGIN
DECLARE #NUM_STR NVARCHAR(MAX)
SET #NUM_STR = #INPUTCSV
SET #NUM_STR = REPLACE(#NUM_STR,' ','')
-- this will trim any intermediate spaces
WHILE LEN(#NUM_STR) >= 0
BEGIN
DECLARE ##SUBSTR VARCHAR(100)
IF CHARINDEX(',',#NUM_STR,0) <> 0
BEGIN
SET ##SUBSTR = SUBSTRING(#NUM_STR,0,CHARINDEX(',',#NUM_STR,0))
INSERT INTO #TBL VALUES(##SUBSTR)
END
ELSE
BEGIN
INSERT INTO #TBL VALUES(#NUM_STR)
BREAK
END
SET ##SUBSTR = ##SUBSTR + ','
SET #NUM_STR = SUBSTRING(#NUM_STR, CHARINDEX(',',#NUM_STR,0) + 1, LEN(#NUM_STR))
END
RETURN
END
I assume you know how to write the overall transform but need help with the tokenization of the string containing the store numbers.
If you're using XSLT 2.0, look at the definition of the tokenize() function. This will split the string value at a specified delimiter, allowing you to perform this transformation. In XSLT 1 you could look at EXSLT regex extension functions.