我有一个要求,我想要if else语句来检查一个节点是否有属性,或者它只是字符串。
例如:节点中的1个具有0 File(s) found
,而另一个节点具有<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
或attrib values
。
答案 0 :(得分:69)
我们可以通过使用以下代码来实现if else
<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>
我的输出
答案 1 :(得分:8)
您可以将整个xsl:choose
指令替换为:
<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>
答案 2 :(得分:4)
<强>予。 Xpath 1.0解决方案 - 使用此单个XPath表达式:
concat(substring('String', 1 div boolean(text())),
' ',
substring('attrib values', 1 div boolean(@*))
)
以下是基于XSLT的验证:
<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
解释我们使用这些事实:
对于任何字符串$s
,substring($s, Infinity)
为空字符串。
1 div 0
是Infinity
根据定义,number(true())
为1
,number(false())
为0。
<强> II。 XPath 2.0解决方案:
这在XPath 2.0中要容易得多,因为该语言具有标准的if/then/else
运算符。
使用强>:
if(text())
then 'String'
else if(@*)
then 'attrib values'
else ()
XSLT 2.0验证:
<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
答案 3 :(得分:3)
XPath //*[not(@*)]
将选择所有没有属性的元素。
答案 4 :(得分:2)
您可以使用xsl:choose
轻松完成此操作 - 但在XSLT中,更常用的方法是编写不同的模板规则来处理不同的条件。因此,使用match="*[@*]"
编写一个模板规则以匹配具有属性的元素,使用match="*[text()]"
编写另一个模板规则以匹配具有文本内容的元素。