XSLT 1.0 帮助条件循环
XSLT 1.0 Help Conditional Looping
我有一个要求,情况如下,
- 如果输入消息记录为空,则我必须在输出消息中填充一个空值
- 如果输入消息记录不为空,那么我必须循环
下面是两个不同的输入消息:
案例一输入:记录为空
<ns0:Root xmlns:ns0="http://Correlation.Input1">
<company>abc</company>
<Token>1243</Token>
</ns0:Root>
案例二输入:多条记录
<ns0:Root xmlns:ns0="http://Correlation.Input1">
<company>abc</company>
<Token>1243</Token>
<Record>
<Name>John</Name>
</Record>
<Record>
<Name>Larry</Name>
</Record>
</ns0:Root>
案例 1 的期望输出:
<ns0:Root xmlns:ns0="http://Correlation.Output">
<Company>abc</Company>
<Token>1243</Token>
<Record>
<Name>Default</Name>
</Record>
</ns0:Root>
案例 2 的期望输出:
<ns0:Root xmlns:ns0="http://Correlation.Output">
<Company>abc</Company>
<Token>1243</Token>
<Record>
<Name>John</Name>
</Record>
<Record>
<Name>Larry</Name>
</Record>
</ns0:Root>
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 s0 userCSharp" version="1.0" xmlns:s0="http://Correlation.Input1" xmlns:ns0="http://Correlation.Output" 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="/s0:Root" />
</xsl:template>
<xsl:template match="/s0:Root">
<xsl:variable name="var:v1" select="count(/s0:Root/Record)" />
<xsl:variable name="var:v2" select="userCSharp:LogicalEq(string($var:v1) , "0")" />
<xsl:variable name="var:v4" select="userCSharp:LogicalNot(string($var:v2))" />
<ns0:Root>
<Company>
<xsl:value-of select="company/text()" />
</Company>
<xsl:if test="Token">
<Token>
<xsl:value-of select="Token/text()" />
</Token>
</xsl:if>
<Record>
<xsl:if test="string($var:v2)='true'">
<xsl:variable name="var:v3" select=""Default"" />
<Name>
<xsl:value-of select="$var:v3" />
</Name>
</xsl:if>
<xsl:if test="string($var:v4)='true'">
<xsl:variable name="var:v5" select=""fgfdg"" />
<Name>
<xsl:value-of select="$var:v5" />
</Name>
</xsl:if>
<xsl:if test="string($var:v4)='true'">
<xsl:variable name="var:v6" select=""fgfdg"" />
<xsl:value-of select="$var:v6" />
</xsl:if>
</Record>
</ns0: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 LogicalNot(string val)
{
return !ValToBool(val);
}
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);
}
public bool ValToBool(string val)
{
if (val != null)
{
if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
{
return false;
}
val = val.Trim();
if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
{
return false;
}
double d = 0;
if (IsNumeric(val, ref d))
{
return (d > 0);
}
}
return false;
}
]]></msxsl:script>
</xsl:stylesheet>
试一试。在调试器中单步执行它。让我知道问题。添加所需的格式。
<xsl:template match="ns0:Root ">
<xsl:copy>
<xsl:apply-templates select="node()"/>
<xsl:if test="not(Record[1])">
<xsl:element name="Record">
<xsl:element name="Name">
<xsl:value-of select="'Default'"/>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:copy>
</xsl:template>
<xsl:template match="Record">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Name">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="company">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="Token">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
你不能简单地做:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://Correlation.Input1"
exclude-result-prefixes="ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="ns0:Root">
<ns0:Root xmlns:ns0="http://Correlation.Output">
<xsl:apply-templates/>
<xsl:if test="not(Record)">
<Record>
<Name>Default</Name>
</Record>
</xsl:if>
</ns0:Root>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" >
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我有一个要求,情况如下,
- 如果输入消息记录为空,则我必须在输出消息中填充一个空值
- 如果输入消息记录不为空,那么我必须循环
下面是两个不同的输入消息:
案例一输入:记录为空
<ns0:Root xmlns:ns0="http://Correlation.Input1">
<company>abc</company>
<Token>1243</Token>
</ns0:Root>
案例二输入:多条记录
<ns0:Root xmlns:ns0="http://Correlation.Input1">
<company>abc</company>
<Token>1243</Token>
<Record>
<Name>John</Name>
</Record>
<Record>
<Name>Larry</Name>
</Record>
</ns0:Root>
案例 1 的期望输出:
<ns0:Root xmlns:ns0="http://Correlation.Output">
<Company>abc</Company>
<Token>1243</Token>
<Record>
<Name>Default</Name>
</Record>
</ns0:Root>
案例 2 的期望输出:
<ns0:Root xmlns:ns0="http://Correlation.Output">
<Company>abc</Company>
<Token>1243</Token>
<Record>
<Name>John</Name>
</Record>
<Record>
<Name>Larry</Name>
</Record>
</ns0:Root>
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 s0 userCSharp" version="1.0" xmlns:s0="http://Correlation.Input1" xmlns:ns0="http://Correlation.Output" 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="/s0:Root" />
</xsl:template>
<xsl:template match="/s0:Root">
<xsl:variable name="var:v1" select="count(/s0:Root/Record)" />
<xsl:variable name="var:v2" select="userCSharp:LogicalEq(string($var:v1) , "0")" />
<xsl:variable name="var:v4" select="userCSharp:LogicalNot(string($var:v2))" />
<ns0:Root>
<Company>
<xsl:value-of select="company/text()" />
</Company>
<xsl:if test="Token">
<Token>
<xsl:value-of select="Token/text()" />
</Token>
</xsl:if>
<Record>
<xsl:if test="string($var:v2)='true'">
<xsl:variable name="var:v3" select=""Default"" />
<Name>
<xsl:value-of select="$var:v3" />
</Name>
</xsl:if>
<xsl:if test="string($var:v4)='true'">
<xsl:variable name="var:v5" select=""fgfdg"" />
<Name>
<xsl:value-of select="$var:v5" />
</Name>
</xsl:if>
<xsl:if test="string($var:v4)='true'">
<xsl:variable name="var:v6" select=""fgfdg"" />
<xsl:value-of select="$var:v6" />
</xsl:if>
</Record>
</ns0: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 LogicalNot(string val)
{
return !ValToBool(val);
}
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);
}
public bool ValToBool(string val)
{
if (val != null)
{
if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
{
return false;
}
val = val.Trim();
if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
{
return false;
}
double d = 0;
if (IsNumeric(val, ref d))
{
return (d > 0);
}
}
return false;
}
]]></msxsl:script>
</xsl:stylesheet>
试一试。在调试器中单步执行它。让我知道问题。添加所需的格式。
<xsl:template match="ns0:Root ">
<xsl:copy>
<xsl:apply-templates select="node()"/>
<xsl:if test="not(Record[1])">
<xsl:element name="Record">
<xsl:element name="Name">
<xsl:value-of select="'Default'"/>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:copy>
</xsl:template>
<xsl:template match="Record">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Name">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="company">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="Token">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
你不能简单地做:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://Correlation.Input1"
exclude-result-prefixes="ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="ns0:Root">
<ns0:Root xmlns:ns0="http://Correlation.Output">
<xsl:apply-templates/>
<xsl:if test="not(Record)">
<Record>
<Name>Default</Name>
</Record>
</xsl:if>
</ns0:Root>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" >
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>