ノードに属性があるか、文字列だけがあるかを確認する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='<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
の値を取得できますか?.
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>
以下のコードを使用して、他の場合に達成できます
<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ソリューション-この単一の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ソリューション:
この言語には標準の_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(' ', 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(@*)]
は、属性を持たないすべての要素を選択します。
これは_xsl:choose
_を使用して十分簡単に実行できますが、XSLTでは非常に頻繁に条件付き処理を行うより良い方法は、さまざまな条件を処理するさまざまなテンプレートルールを記述することです。したがって、1つのテンプレートルールを_match="*[@*]"
_で記述して属性を持つ要素に一致させ、別のテンプレートルールをmatch="*[text()]"
で記述してテキストコンテンツを持つ要素に一致させます。