web-dev-qa-db-ja.com

ノードに少なくとも1つの空でない子が含まれているかどうかを確認するXSL / XPath式

XMLノードに少なくとも1つの空でない子があるかどうかを確認する必要があります。このXMLに適用される式はtrueを返す必要があります

_<xml>
    <node>
       <node1/>
       <node2/>
       <node3>value</node3>
    </node>
</xml>
_

私はこの式を使用しようとしました:<xsl:if test="not(/xml/node/child::* = '')">が、all子が空でないかどうかをチェックするようです。

少なくとも1つ要素が空でない場合、trueを返す式を作成するにはどうすればよいですか?ノードchldrenを反復処理する別のテンプレートを作成せずにこれを行う方法はありますか?

PD:空ではないノードを次のようにカウントすることを考えています
test="count(not(/xml/node/child::* = '')) &gt; '0'"
しかし、どういうわけかそれを正しく動作させることができません。この式は整形式ではありません。

27
svz

より正確でシンプルかつ効率的(count()関数を使用する必要はありません)

  /*/node/*[text()]

空白のみのテキストの子のみを持つ要素を除外する場合は、次を使用します:

  /*/node/*[normalize-space()]
33

必要なのは<xsl:if test="/xml/node/* != ''" />

XPathでは=または!=比較は、セットのノードのanyが比較に合格した場合、一方がノードセットで、もう一方が文字列である場合に成功します。かくして

not(x = '')

「現在のノードのx子要素に空の文字列値があるということではない」ことを意味します。これは、

x != ''

これは、「現在のノードの少なくとも1つのx子要素に空でない文字列値がある」ことを意味します。特に、allxの子が空であることを確認したい場合は、「二重否定」テストを使用する必要があります

not(x != '')
11
Ian Roberts

このジョブを実行するXPathが1つあります。

_count(/*/node/*[text()]) &gt; 0
_

サンプルXSLTで使用する場合:

_<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
     <xsl:value-of select="count(/*/node/*[text()]) &gt; 0" />
  </xsl:template>

</xsl:stylesheet>
_

...次に、提供されたサンプルXMLに適用されます:

_<xml>
  <node>
    <node1/>
    <node2/>
    <node3>value</node3>
  </node>
</xml>
_

...期待される結果が生成されます:

_true
_

単純に変更されたXMLに対して同じXSLTを適用する場合:

_<xml>
  <node>
    <node1/>
    <node2/>
    <node3/>
  </node>
</xml>
_

...再び、期待される結果が生成されます:

_false
_

説明:

使用されたXPathは、空でないテキスト値(text()で指定された)を持つ_<node>_要素のすべての子(ルート要素の子)を検索します。そのような_<node>_子のカウントが0より大きい場合、XPathはtrueに解決されます。

4
ABach
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:value-of select="/*/node/*[string-length(text()) &gt;0]!=''"/>
    </xsl:template>
</xsl:stylesheet>

説明これは、ゼロより長い文字列の長さを持つ最初のノードを見つけ、そのようなノードの内容を空の文字列と比較します(比較は空でない文字列ノードの存在を返します);このコードは、任意のノードで特定の基準を検索するためにも使用できます。たとえば、特定の文字列を含むか、何らかの文字または他の条件で始まるノードの存在を識別します。コードのマジックを機能させるために、これをノード参照の内部条件として使用してください。

0
HectorYep