XSL if else条件

时间:2011-08-30 06:07:13

标签: xml xslt xpath

我有一个要求,我想要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='&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>

我如何识别节点是否只有字符串或属性,并且基于此我可以分别获得值Stringattrib values

5 个答案:

答案 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>

我的输出

enter image description here

答案 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('&#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. 对于任何字符串$ssubstring($s, Infinity)为空字符串。

  2. 1 div 0Infinity

  3. 根据定义,number(true())1number(false())为0。

    <强> II。 XPath 2.0解决方案:

  4. 这在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('&#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
    

答案 3 :(得分:3)

XPath //*[not(@*)]将选择所有没有属性的元素。

答案 4 :(得分:2)

您可以使用xsl:choose轻松完成此操作 - 但在XSLT中,更常用的方法是编写不同的模板规则来处理不同的条件。因此,使用match="*[@*]"编写一个模板规则以匹配具有属性的元素,使用match="*[text()]"编写另一个模板规则以匹配具有文本内容的元素。