Reputation: 161
<Employees xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ListItems>
<Employee>
<EmployeeNo>123456</EmployeeNo>
<FirstName>firstName</FirstName>
<LastName>lastName</LastName>
<Email>[email protected]</Email>
<Active>true</Active>
</Employee>
</ListItems>
</Employees>
XSLT
<xsl:template match="Employee[count(descendant::Active[. = '']) = 1]">
<xsl:variable name="Active">
<!--<xsl:for-each select="Employees/ListItems/Employee">-->
<xsl:choose>
<xsl:when test="Active='true'">
<Active>Y</Active>
</xsl:when>
<xsl:otherwise>
<Active>N</Active>
</xsl:otherwise>
</xsl:choose>
<!--</xsl:for-each>-->
</xsl:variable>
</xsl:template>
I need to write an xslt when employee's record Active = true, I need to transform true to "Y", if not then "N". I wrote this XSLT but it not working
Currently = true What I need to have is = Y
Upvotes: 1
Views: 1188
Reputation: 117165
To simplify the matter, try the following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Active">
<xsl:copy>
<xsl:choose>
<xsl:when test=".='true'">Y</xsl:when>
<xsl:otherwise>N</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
P.S. This solution proudly uses xsl:choose
. xsl:choose
is an integral part of the XSLT language, and there is absolutely nothing wrong with using it to its full advantage. It adds clarity to the code, while artificial attempts to avoid using it only end up obfuscating the code unnecessarily.
Upvotes: 1
Reputation: 243599
This short and simple transformation (only two templates, no explicit conditional instructions, no repeated <xsl:copy>
, no <xsl:choose>
, <xsl:when>
or <xsl:otherwise>
):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Employee/Active/text()">
<xsl:value-of select="substring('YN', 2 - (.= 'true'), 1)"/>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied on the following source XML document:
<Employees>
<ListItems>
<Employee>
<EmployeeNo>123456</EmployeeNo>
<FirstName>firstName</FirstName>
<LastName>lastName</LastName>
<Email>[email protected]</Email>
<Active>true</Active>
</Employee>
<Employee>
<EmployeeNo>234567</EmployeeNo>
<FirstName>firstName2</FirstName>
<LastName>lastName2</LastName>
<Email>[email protected]</Email>
<Active>not-quite-true</Active>
</Employee>
</ListItems>
</Employees>
produces the wanted, correct result:
<Employees>
<ListItems>
<Employee>
<EmployeeNo>123456</EmployeeNo>
<FirstName>firstName</FirstName>
<LastName>lastName</LastName>
<Email>[email protected]</Email>
<Active>Y</Active>
</Employee>
<Employee>
<EmployeeNo>234567</EmployeeNo>
<FirstName>firstName2</FirstName>
<LastName>lastName2</LastName>
<Email>[email protected]</Email>
<Active>N</Active>
</Employee>
</ListItems>
</Employees>
Explanation:
Active
element that is a child of an Employee
element'YN'
with length 1 and offset determined by 2 - (.= 'true')
-- where we use the fact that in XPath 1.0 if a Boolean value is an argument of an arithmetic operation, true()
is converted to 1
and false()
is converted to 0
Upvotes: 0
Reputation: 338406
You want to modify <Active>
nodes, specifically.
So write templates just for them and let the identity template deal with all other nodes:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<!-- <Active> with a value of 'true': switch value to 'Y' -->
<xsl:template match="Employee//Active[. = 'true']">
<xsl:copy>Y</xsl:copy>
</xsl:template>
<!-- <Active> with any other value: switch value to 'N' -->
<xsl:template match="Employee//Active[. != 'true']">
<xsl:copy>N</xsl:copy>
</xsl:template>
<!-- identity template - copy all nodes that have no better template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
result:
<Employees xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ListItems>
<Employee>
<EmployeeNo>123456</EmployeeNo>
<FirstName>firstName</FirstName>
<LastName>lastName</LastName>
<Email>[email protected]</Email>
<Active>Y</Active>
</Employee>
</ListItems>
</Employees>
Upvotes: 2