37 votes

XSL si autre condition

J'ai une exigence où je voudrais avoir si autre déclaration pour vérifier si un nœud a des attributs ou il a juste une chaîne.

Ex: 1 du noeud a 0 File(s) found et l'autre a des attributs tels que <autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='64' filename='AFP_p.tgp' />

Ci-dessous un échantillon de deux nœuds

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

Comment pourrais-je identifier si un nœud a seulement des chaînes ou des attributs et sur cette base, je peux obtenir les valeurs respectivement String ou attrib values .

70voto

Abhishek Simon Points 2607

Nous pouvons réaliser si sinon en utilisant le code ci-dessous

 <xsl:choose>
    <xsl:when test="something to test">

    </xsl:when>
    <xsl:otherwise>

    </xsl:otherwise>
</xsl:choose>
 

Alors voici ce que j'ai fait

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

Ma sortie

entrez la description de l'image ici

8voto

empo Points 12803

Vous pouvez remplacer l’ensemble de vos instructions xsl:choose par:

 <xsl:apply-templates select="autoIncludeSystem"/>
 

puis ajoutez deux modèles:

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

4voto

Dimitre Novatchev Points 147842

I. Xpath 1.0 solution - utiliser cette expression XPath:

concat(substring('String', 1 div boolean(text())),
                 ' ',
       substring('attrib values', 1 div boolean(@*))
       )

Voici un XSLT vérification basée sur:

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

lorsque cette transformation est appliquée sur le document XML (légèrement modifiée pour être bien formé):

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

le voulais, résultat correct est produit:

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

Explication Nous utilisons ces faits:

  1. Pour toute chaîne de caractères $s, substring($s, Infinity) est la chaîne vide.

  2. 1 div 0 est Infinity

  3. Par définition, number(true()) est 1 et number(false()) est de 0.

    II. XPath 2.0 solution:

C'est beaucoup plus facile dans XPath 2.0, parce que la langue est la norme if/then/else de l'opérateur.

Utilisation:

if(text())
  then 'String'
  else if(@*)
         then 'attrib values'
         else ()

XSLT 2.0 vérification:

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

lorsque cette transformation est appliquée sur le même document XML (ci-dessus), de nouveau le voulait, résultat correct est produit:

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

3voto

Kirill Polishchuk Points 28058

XPath //*[not(@*)] sélectionnera tous les éléments qui ne possèdent pas d'attributs.

3voto

Michael Kay Points 52194

Vous pouvez le faire assez facilement en utilisant xsl:choose - mais très souvent en XSLT, le meilleur moyen d'effectuer un traitement conditionnel est d'écrire différentes règles de modèle pour gérer les différentes conditions. Écrivez donc une règle de modèle avec match="*[@*]" pour faire correspondre les éléments ayant des attributs, et une autre avec match="*[text()]" pour faire correspondre les éléments ayant un contenu textuel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X