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='&lt;DIR&gt;' 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('&#10;', 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='&lt;DIR&gt;' 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 

解释我们使用这些事实:

  1. 对于任何string$ssubstring($s, Infinity)是空string。

  2. 1 div 0Infinity

  3. 根据定义number(true())1number(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('&#10;', 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()]"来匹配具有文本内容的元素。