セット操作 (XPath)

XML Path 言語 (XPath) は集合演算 ||.

UNION (|) 演算子

| Union 演算子は 2 つのオペランドの和集合を返します。オペランドはノードセットでなければなりません。 たとえば //author | //publisher は、すべての //author ノードとすべての //publisher ノードを結合した 1 つのノード セットを返します。 複数の UNION 演算子を続けて、複数のノード セットを結合することができます。 たとえば、//author | //publisher | //editor | //book-seller は、すべての //author、//publisher、//editor、および //book-seller elements を含むノード セットを返します。 UNION 演算子はドキュメントの順序を維持し、重複してノードを返すことはありません。

説明

first-name | last-name

現在のコンテキストの <first-name> 要素と <last-name> 要素を含むノード セット。

(bookstore/book | bookstore/magazine)

<bookstore> 要素の中で、<book> 要素または <magazine> 要素を含むノード セット。

book | book/author

すべての <book> 要素と <book> 要素内のすべての <author> 要素を含むノード セット。

(book | magazine)/price

<book> 要素または <magazine> 要素内の <price> 要素をすべて含むノード セット。

次の例で UNION 演算子の効果について説明します。

ms256074.collapse_all(ja-jp,VS.120).gifXML ファイル (test.xml)

<?xml version="1.0"?>
<test>
    <x a="1">
      <x a="2" b="B">
        <x>
          <y>y31</y>
          <y>y32</y>
        </x>
      </x>
    </x>
</test>

ms256074.collapse_all(ja-jp,VS.120).gifXSLT ファイル (test.xsl)

次の XSLT スタイル シートは、a 属性が 2 に等しいすべての <x> 要素と、属性を持たない <x> 要素を選択します。

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

   <!-- Suppress text nodes not covered in subsequent template rule. -->
   <xsl:template match="text()"/>

  <!-- Handles a generic element node. -->
   <xsl:template match="*">
      <xsl:element name="{name()}">
         <xsl:apply-templates select="*|@*" />
         <xsl:if test="text()">
            <xsl:value-of select="."/>
         </xsl:if>
      </xsl:element>
   </xsl:template>

   <!-- Handles a generic attribute node. -->
   <xsl:template match="@*">
      <xsl:attribute name="{name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>

   <xsl:template match="/test">
      <xsl:apply-templates select="//x[@a=2] | //x[not(@*)]"/>
   </xsl:template>

</xsl:stylesheet>

変換により次の結果が得られます。

<x a="2" b="B">
   <x>
      <y>31</y>
      <y>y32</y>
   </x>
</x>
<x>
   <y>y31</y>
   <y>y32</y>
</x>

優先順位

ブール型演算子と比較演算子の間の優先順位 (最優先度から順に) を次の表に示します。

優先順位

演算子

説明

1

( )

グループ化

2

[ ]

フィルター

3

/

//

Path 演算

4

&lt;

&lt;=

&gt;

&gt;=

比較

5

=

!=

比較

6

|

和集合

7

not()

ブール型演算子 not

8

and

ブール型演算子 and

9

or

ブール型演算子 or

ms256074.collapse_all(ja-jp,VS.120).gif

次の例で、上記演算子の優先順位が及ぼす効果について説明します。

ms256074.collapse_all(ja-jp,VS.120).gifXML ファイル (test.xml)

<?xml version="1.0"?>
<test>

    <x a="1">
      <x a="2" b="B">
        <x>
          <y>y31</y>
          <y>y32</y>
        </x>
      </x>
    </x>

    <x a="1">
      <x a="2">
        <y>y21</y>
        <y>y22</y>
      </x>
    </x>

    <x a="1">
      <y>y11</y>
      <y>y12</y>
    </x>

    <x>
      <y>y03</y>
      <y>y04</y>
    </x>

</test>

ms256074.collapse_all(ja-jp,VS.120).gif基本 XSLT ファイル (test.xsl)

以降に続く一連の説明の出発点として、この基本 XSLT ファイルを使用します。

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

   <!-- Suppress text nodes not covered in subsequent template rule. -->
   <xsl:template match="text()"/>

  <!-- Handles a generic element node. -->
   <xsl:template match="*">
      <xsl:element name="{name()}">
         <xsl:apply-templates select="*|@*" />
         <xsl:if test="text()">
            <xsl:value-of select="."/>
         </xsl:if>
      </xsl:element>
   </xsl:template>

   <!-- Handles a generic attribute node. -->
   <xsl:template match="@*">
      <xsl:attribute name="{name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>

</xsl:stylesheet>

ms256074.collapse_all(ja-jp,VS.120).gifケース 0: テスト実行

次のテンプレート規則を XSLT スタイル シートに追加することができます。

<xsl:template match="/test">
      <xsl:apply-templates select="*|@*/>
   </xsl:template>

これにより、<?xml version="1.0"?> 処理命令のない、オリジナルと同一の XML ドキュメントが生成されます。

次の各ケースで、このテンプレート規則を書く各種の方法を示します。 要点は、XPath 演算子が要素に結び付けられる順序を示すことです。

ms256074.collapse_all(ja-jp,VS.120).gifケース 1 : () は [] よりも強固に結び付く

次のテンプレートは、ソース ドキュメントのすべての <y> 要素の中から、ドキュメント内の順で最初の <y> 要素を選択します。

<xsl:template match="/test">
      <xsl:apply-templates select="(//y)[1]"/>
   </xsl:template>

この結果は次のようになります。

<y>y31</y>

ms256074.collapse_all(ja-jp,VS.120).gifケース 2 : [] は / や // よりも強固に結び付く

次のテンプレート規則は、兄弟の中で最初の <y> 要素をすべて選択します。

<xsl:template match="/test">
   <xsl:apply-templates select="//y[1]"/>
</xsl:template>

この結果は次のようになります。

<y>y31</y>

<y>y21</y>

<y>y11</y>

<y>y03</y>

ms256074.collapse_all(ja-jp,VS.120).gifケース 3 : and、not

次のテンプレート規則は、子要素 <x> を持たず、親要素 <x> を持ち、属性をまったく持たない <x> 要素をすべて選択します。

<xsl:template match="/test">
   <xsl:apply-templates select=
    "//x[./ancestor::*[name()='x'] and *[name()!='x'] and not(@*)]"/>
</xsl:template>

結果は、子と共に下に一覧される 1 つの <x> 要素です。

<x>
   <y>y31</y>
   <y>y32</y>
</x>

ms256074.collapse_all(ja-jp,VS.120).gifケース 4 : or、and、not

次のテンプレート規則は、<x> 要素の子であるか、または <x> 要素の親でなく属性をまったく持たない、各 <x> 要素を選択します。

<xsl:template match="/test">
   <xsl:apply-templates select=
    "//x[./ancestor::*[name()='x'] or *[name()!='x'] and not(@*)]"/>
</xsl:template>

結果は、子と共に下に一覧された、次の <x> 要素を含むノード セットです。

<x a="2" b="B">
  <x>
     <y>y31</y>
     <y>y32</y>
  </x>
</x>
<x>
  <y>y31</y>
  <y>y32</y>
</x>
<x a="2">
  <y>y21</y>
  <y>y22</y>
</x>
<x>
  <y>y03</y>
  <y>y04</y>
</x>

ms256074.collapse_all(ja-jp,VS.120).gifケース 5 : and、or、not

次のテンプレート規則は、<x> 要素の子であるが <x> 要素の親ではない <x> 要素、または属性を持たない <x> 要素を選択します。

<xsl:template match="/test">
   <xsl:apply-templates select=
    "//x[./ancestor::*[name()='x'] and *[name()!='x'] or not(@*)]"/>
</xsl:template>

結果は、子と共に下に一覧された、次の <x> 要素を含むノード セットです。

<x>
   <y>y31</y>
   <y>y32</y>
</x>
<x a="2">
  <y>y21</y>
  <y>y22</y>
</x>
<x>
  <y>y03</y>
  <y>y04</y>
</x>