XSL if else条件
我有一个要求,如果我想要有其他语句来检查一个节点是否有属性或它只是string。
例如:节点1有0 File(s) found ,另一个有<autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='64' filename='AFP_p.tgp' /> ,如<autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='64' filename='AFP_p.tgp' /> 
以下是两个节点的示例
 <product> <autoIncludeUser>0 File(s) found</autoIncludeUser> <autoIncludeSystem> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='64' filename='AFP_p.tgp' /> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='3,879' filename='AnalystsExpressionMacros.tgp' /> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='475' filename='base64Converter.tgp' /> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='<DIR>' filename='codePages' /> </autoIncludeSystem> <autoIncludeStudio>0 File(s) found</autoIncludeStudio> <externalLibrarySystem> <externalLibrarySystem_info mdate='08/23/2011' mtime='09:52' ampm='PM' filesize='196,608' filename='AFPtoXML_DP.dll' /> <externalLibrarySystem_info mdate='08/23/2011' mtime='09:52' ampm='PM' filesize='13,259' filename='ASN1toXSDRunner.jar' /> <externalLibrarySystem> </product> 
 我将如何确定节点是否只有string或属性,并基于我可以分别获取值或String attrib values 。 
 您可以将您的整个xsl:choose指令replace为: 
 <xsl:apply-templates select="autoIncludeSystem"/> 
然后添加两个模板:
 <xsl:template match="autoIncludeSystem[autoincludesystem_info/@*]> <!-- code for elements with attributes (xsl:when) --> </xsl:template> <xsl:template match="autoIncludeSystem[not(autoincludesystem_info/@*)]> <!-- code for elements without attributes (xsl:otherwise) --> </xsl:template> 
我们可以通过使用下面的代码来实现
 <xsl:choose> <xsl:when test="something to test"> </xsl:when> <xsl:otherwise> </xsl:otherwise> </xsl:choose> 
所以这就是我所做的
 <h3>System</h3> <xsl:choose> <xsl:when test="autoIncludeSystem/autoincludesystem_info/@mdate"> <!-- if attribute exists--> <p> <dd><table border="1"> <tbody> <tr> <th>File Name</th> <th>File Size</th> <th>Date</th> <th>Time</th> <th>AM/PM</th> </tr> <xsl:for-each select="autoIncludeSystem/autoincludesystem_info"> <tr> <td valign="top" ><xsl:value-of select="@filename"/></td> <td valign="top" ><xsl:value-of select="@filesize"/></td> <td valign="top" ><xsl:value-of select="@mdate"/></td> <td valign="top" ><xsl:value-of select="@mtime"/></td> <td valign="top" ><xsl:value-of select="@ampm"/></td> </tr> </xsl:for-each> </tbody> </table> </dd> </p> </xsl:when> <xsl:otherwise> <!-- if attribute does not exists --> <dd><pre> <xsl:value-of select="autoIncludeSystem"/><br/> </pre></dd> <br/> </xsl:otherwise> </xsl:choose> 
我的输出

I. Xpath 1.0解决scheme – 使用这个XPathexpression式 :
 concat(substring('String', 1 div boolean(text())), ' ', substring('attrib values', 1 div boolean(@*)) ) 
以下是基于XSLT的validation :
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="*[not(*)]"> <xsl:value-of select="concat('
', name(),': ')"/> <xsl:value-of select= "concat(substring('String', 1 div boolean(text())), ' ', substring('attrib values', 1 div boolean(@*)) ) "/> </xsl:template> </xsl:stylesheet> 
当对所提供的XML文档应用这种转换 (稍作纠正以使其格式良好)时:
 <product> <autoIncludeUser>0 File(s) found</autoIncludeUser> <autoIncludeSystem> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='64' filename='AFP_p.tgp' /> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='3,879' filename='AnalystsExpressionMacros.tgp' /> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='475' filename='base64Converter.tgp' /> <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='<DIR>' filename='codePages' /> </autoIncludeSystem> <autoIncludeStudio>0 File(s) found</autoIncludeStudio> <externalLibrarySystem> <externalLibrarySystem_info mdate='08/23/2011' mtime='09:52' ampm='PM' filesize='196,608' filename='AFPtoXML_DP.dll' /> <externalLibrarySystem_info mdate='08/23/2011' mtime='09:52' ampm='PM' filesize='13,259' filename='ASN1toXSDRunner.jar' /> </externalLibrarySystem> </product> 
想要的,正确的结果是 :
 autoIncludeUser: String autoincludesystem_info: attrib values autoincludesystem_info: attrib values autoincludesystem_info: attrib values autoincludesystem_info: attrib values autoIncludeStudio: String externalLibrarySystem_info: attrib values externalLibrarySystem_info: attrib values 
解释我们使用这些事实:
- 
对于任何string $s,substring($s, Infinity)是空string。
- 
1 div 0是Infinity
- 
根据定义 number(true())是1,number(false())是0。II。 XPath 2.0解决scheme : 
 这在XPath 2.0中要容易得多,因为该语言具有标准的if/then/else运算符。 
用途 :
 if(text()) then 'String' else if(@*) then 'attrib values' else () 
XSLT 2.0validation:
 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="*[not(*)]"> <xsl:value-of select="concat('
', name(),': ')"/> <xsl:value-of select= "if(text()) then 'String' else if(@*) then 'attrib values' else () "/> </xsl:template> </xsl:stylesheet> 
当这个转换应用于同一个XML文档(上面)时,又会产生所需的正确结果 :
 autoIncludeUser: String autoincludesystem_info: attrib values autoincludesystem_info: attrib values autoincludesystem_info: attrib values autoincludesystem_info: attrib values autoIncludeStudio: String externalLibrarySystem_info: attrib values externalLibrarySystem_info: attrib values 
  XPath //*[not(@*)]将select所有没有属性的元素。 
 您可以使用xsl:choose轻松地完成此操作,但是在XSLT中,通常情况下,执行条件处理的更好方法是编写不同的模板规则来处理不同的条件。 因此,写一个match="*[@*]"模板规则来匹配具有属性的元素,另一个match="*[text()]"来匹配具有文本内容的元素。