web-dev-qa-db-ja.com

XSL if else条件

ノードに属性があるか、文字列だけがあるかを確認するif elseステートメントが必要な要件があります。

例:ノードの1つには0 File(s) foundがあり、もう1つには<autoincludesystem_info mdate='08/23/2011' mtime='09:51' ampm='PM' filesize='64' filename='AFP_p.tgp' />などの属性があります

以下は2つのノードのサンプルです

<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またはattrib valuesの値を取得できますか?.

36
abi1964

xsl:choose命令全体を次のように置き換えることができます。

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

次に、2つのテンプレートを追加します。

<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>
8
Emiliano Poggi

以下のコードを使用して、他の場合に達成できます

<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

69
abi1964

I。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. すべての文字列_$s_の場合、substring($s, Infinity)は空の文字列です。

  2. _1 div 0_はInfinityです

  3. 定義により、number(true())は_1_であり、number(false())は0です。

    II。XPath 2.0ソリューション

この言語には標準の_if/then/else_演算子があるため、XPath 2.0の方がはるかに簡単です。

使用

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

XPath //*[not(@*)]は、属性を持たないすべての要素を選択します。

3

これは_xsl:choose_を使用して十分簡単に​​実行できますが、XSLTでは非常に頻繁に条件付き処理を行うより良い方法は、さまざまな条件を処理するさまざまなテンプレートルールを記述することです。したがって、1つのテンプレートルールを_match="*[@*]"_で記述して属性を持つ要素に一致させ、別のテンプレートルールをmatch="*[text()]"で記述してテキストコンテンツを持つ要素に一致させます。

2
Michael Kay