Hi Jil22,
To achieve desired result you will have to include root node in destination schema without root node u can achieve but it ll give you error like "there are multiple root node". for this you will have to use passthru in both side.
Try below xslt.
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var userCSharp" version="1.0" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="/">
<xsl:apply-templates select="/ListKey" />
</xsl:template>
<xsl:template match="/ListKey">
<Root>
<xsl:for-each select="Key">
<xsl:variable name="var:isvalid" select="@isvalid" />
<xsl:variable name="var:id" select="@id" />
<xsl:choose>
<xsl:when test="@isvalid='true'">
<xsl:for-each select="ListDateOk/DateOk">
<Key>
<xsl:attribute name="IsValid">
<xsl:value-of select="$var:isvalid" />
</xsl:attribute>
<xsl:attribute name="id">
<xsl:value-of select="$var:id" />
</xsl:attribute>
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(../../@isvalid) , "true")" />
<xsl:if test="$var:v1">
<xsl:variable name="var:v2" select="string(../../@isvalid)" />
<xsl:variable name="var:v3" select="userCSharp:LogicalEq($var:v2 , "true")" />
<DateOk>
<xsl:if test="string($var:v3)='true'">
<xsl:variable name="var:v4" select="@date" />
<xsl:attribute name="date">
<xsl:value-of select="$var:v4" />
</xsl:attribute>
</xsl:if>
</DateOk>
</xsl:if>
</Key>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<Key>
<xsl:attribute name="IsValid">
<xsl:value-of select="$var:isvalid" />
</xsl:attribute>
<xsl:attribute name="id">
<xsl:value-of select="$var:id" />
</xsl:attribute>
</Key>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</Root>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public bool LogicalEq(string val1, string val2)
{
bool ret = false;
double d1 = 0;
double d2 = 0;
if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
{
ret = d1 == d2;
}
else
{
ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
}
return ret;
}
public bool IsNumeric(string val)
{
if (val == null)
{
return false;
}
double d = 0;
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public bool IsNumeric(string val, ref double d)
{
if (val == null)
{
return false;
}
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
]]></msxsl:script>
</xsl:stylesheet>
Input Instance:
<ListKey>
<Key isvalid="true" id="2">
<ListDateOk>
<DateOk date="2015-08-20" />
</ListDateOk>
</Key>
<Key isvalid="false" id="3"/>
<Key isvalid="true" id="4">
<ListDateOk>
<DateOk date="2015-08-21" />
<DateOk date="2015-08-22" />
<DateOk date="2015-08-23" />
</ListDateOk>
</Key>
</ListKey>
OutPut Instance:
<Root>
<Key IsValid="true" id="2">
<DateOk date="2015-08-20"></DateOk>
</Key>
<Key IsValid="false" id="3">
</Key>
<Key IsValid="true" id="4">
<DateOk date="2015-08-21"></DateOk>
</Key>
<Key IsValid="true" id="4">
<DateOk date="2015-08-22"></DateOk>
</Key>
<Key IsValid="true" id="4">
<DateOk date="2015-08-23"></DateOk>
</Key>
</Root>
It will help you.