importとincludeの違い

はじめに

どちらも指定位置に別ファイルのxsltを読込む<xsl:import><xsl:include>だが,違いがいまいちよくわからない.ということで,Saxon 8.5を使って試してみた.

同じ名前のテンプレートを定義していた場合

<xsl:import><xsl:include>では,優先順の扱いが違う.ということで,まず同じ名前のテンプレートを作ってみた.

<!-- 読込まれるスタイルシート -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    source root
  </xsl:template>
</xsl:stylesheet>

<!-- importで読込む -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="source.xsl"/>

  <xsl:template match="/">
    import root
  </xsl:template>
</xsl:stylesheet>

<!-- includeで読込む -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="source.xsl"/>

  <xsl:template match="/">
    include root
  </xsl:template>
</xsl:stylesheet>

<!-- テスト用xml -->
<?xml version="1.0" encoding="utf-8"?>
<root>
  sample
</root>

Saxonをコマンドラインから動かすと,結果は以下のようになる.なお,${saxon_home}はSaxonをインストールしたディレクトリを表す.

importの場合

$ java -jar ${saxon_home}/saxon8.jar -novw sam.xml import.xsl
<?xml version="1.0" encoding="UTF-8"?>
                import root

includeの場合

$ java -jar ${saxon_home}/saxon8.jar -novw sam.xml include.xsl
Recoverable error
  XTRE0540: Ambiguous rule match for /
Matches both "document-node()" on line 5 of
  file:/c:/Documents%20and%20Settings/satoshi/My%20Documents/ant/include.xsl
and "document-node()" on line 3 of
  file:/c:/Documents%20and%20Settings/satoshi/My%20Documents/ant/source.xsl
<?xml version="1.0" encoding="UTF-8"?>
                include root

importの場合は,<xsl:import>を書いたファイルにあるテンプレートを優先し,includeの場合は優先度の高低がないためルールが重複する.

優先度を指定してみよう

<xsl:import><xsl:include>priority属性を指定してみた.

<!-- importで読込む -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="source.xsl"/>

  <xsl:template match="/" priority="-1">
    import root
  </xsl:template>
</xsl:stylesheet>

<!-- includeで読込む -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="source.xsl"/>

  <xsl:template match="/" priority="-1">
    include root
  </xsl:template>
</xsl:stylesheet>

importの場合

$ java -jar ${saxon_home}/saxon8.jar -novw sam.xml import.xsl
<?xml version="1.0" encoding="UTF-8"?>
                import root

includeの場合

$ java -jar ${saxon_home}/saxon8.jar -novw sam.xml include.xsl
<?xml version="1.0" encoding="UTF-8"?>
                source root

importはpriority属性の値を無視して優先度を決め,includeはpriority属性の値によって優先度が決まっている.<xsl:include>でもう一つ試してみよう.

<!-- includeで読込む -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="source.xsl"/>

  <xsl:template match="/" priority="1">
    include root
  </xsl:template>
</xsl:stylesheet>

$ java -jar ${saxon_home}/saxon8.jar -novw sam.xml include.xsl
<?xml version="1.0" encoding="UTF-8"?>
                include root

<xsl:include>を指定したスタイルシートに定義したテンプレートが優先となった.

まとめ

importでファイルを読込む場合は,

  • importを記述したファイルのテンプレートが優先度高.href属性に指定したファイルは優先度低
  • priority属性で値を指定しても優先度を変更することはできない

includeでファイルを読込む場合は,

  • includeを記述したファイル,includeのhref属性に指定したファイル両方のテンプレートに優先度の高低はない
  • priority属性で値を指定することで優先度を変更することができる