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()]"
来匹配具有文本内容的元素。