連載

.NETで簡単XML

第6回 .NETプログラムでXSLTスクリプトを使う

株式会社ピーデー 川俣 晶
2003/07/08

プログラムでXSLTスクリプトを処理させる

 さて、ここまではWebブラウザ内で完結する世界であったが、当然のことながら我々は別の世界に住んでいる。自作プログラムからXSLTを使いこなすことが、我々の今回の目標である。それにはどうすればよいのだろうか。

 XSLTスクリプトファイルとXML文書ファイルを読み込んで、結果をファイル出力するだけのプログラムは簡単に作ることができる。以下にその例を示す。

<?xml version="1.0" encoding="UTF-8" ?>
<database>
  <person>
    <name>伊能忠敬</name>
    <birth>1745</birth>
  </person>
  <person>
    <name>間宮林蔵</name>
    <birth>1775</birth>
  </person>
</database>
プログラムで処理するXML文書(c:\sample04.xml)
 
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" />

  <xsl:template match="person">
    <xsl:value-of select="name" />
  </xsl:template>

  <xsl:template match="/">
    <result><xsl:apply-templates select="/database/person[birth = 1775]" /></result>
  </xsl:template>
</xsl:stylesheet>
プログラムで処理するXSLTスクリプト(c:\sample04.xslt)

 上記のXML文書とXSLTスクリプトを読み込んで処理するプログラムは次のようになる。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim xslt As XslTransform = New XslTransform
  xslt.Load("c:\sample04.xslt")
  xslt.Transform("c:\sample04.xml", "c:\result.xml", Nothing)
End Sub
XML文書sample04.xmlとXSLTスクリプトsample04.xsltを読み込んで結果を出力するサンプル・プログラム(VB.NET版C#版

 このプログラムを実行すると、処理結果をc:\result.xmlというファイルに出力する。その内容は以下のようになる。

<?xml version="1.0" encoding="utf-8"?><result>間宮林蔵</result>
実行結果(c:\result.xml)

 さて、ここで注目すべき個所は、もちろん、XslTransformクラスを使った処理である。このプログラムではXslTransformクラスのインスタンスを作成してそのLoadメソッドを呼び出し、さらにTransformメソッドを呼び出している。これだけで変換処理は完了である。Loadメソッドは、XSLTスクリプトを読み込むために使用される。そしてTransformメソッドは、入力するXML文書のファイル名と出力するXML文書のファイル名を指定している。Transformメソッドの第3引数にNothing(C#ではnull)を指定しているが、この引数はXSLTのdocument()関数を使う場合に必要とされるものである。ここにはXmlResolverと呼ばれるものを指定するが、今回のサンプルではdocument()関数を使用していないのでここではNothing(C#ではnull)を指定している。

 本筋とは離れるが、XSLTスクリプトの内容も説明しておこう。このXSLTスクリプトはbirth要素の値が1775であるperson要素を探し出し、その子要素のname要素の値をresult要素の値として出力している。xsl:output要素のmethod属性の値が「xml」になっているので、出力されるものはXML文書となる。そのため、実行結果の先頭にはXML宣言が付加されている。

プログラム内のデータを変換する

 前の例はファイルとして存在するXSLTスクリプトとXML文書を読み込んで、XML文書をファイルとして出力した。だが、プログラム内部でXSLTを活用するとなると、いつも処理の対象がファイルになるとは限らない。例えば、文字列として存在するXML文書を処理して、結果を文字列として得たい場合もあるだろう。そのような機能を記述した例を以下に示す。

Private Const xsltStyleSheet As String = "<?xml version='1.0' encoding='UTF-8' ?>" + vbCrLf _
  & "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" & vbCrLf _
  & "  <xsl:template match='person'>" & vbCrLf _
  & "  <xsl:value-of select='name' />" & vbCrLf _
  & "  </xsl:template>" & vbCrLf _
  & "  <xsl:template match='/'>" & vbCrLf _
  & "  <result><xsl:apply-templates select='/database/person[birth = 1775]' /></result>" & vbCrLf _
  & "  </xsl:template>" & vbCrLf _
  & "</xsl:stylesheet>" & vbCrLf

Private Const xmlDocument As String = "<?xml version='1.0' encoding='UTF-8' ?>" & vbCrLf _
  & "<database>" & vbCrLf _
  & "  <person>" & vbCrLf _
  & "  <name>伊能忠敬</name>" & vbCrLf _
  & "  <birth>1745</birth>" & vbCrLf _
  & "  </person>" & vbCrLf _
  & "  <person>" & vbCrLf _
  & "  <name>間宮林蔵</name>" & vbCrLf _
  & "  <birth>1775</birth>" & vbCrLf _
  & "  </person>" & vbCrLf _
  & "</database>" & vbCrLf

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim xslt As XslTransform = New XslTransform
  xslt.Load(New XmlTextReader(New StringReader(xsltStyleSheet)), Nothing, Nothing)
  Dim document As XmlDocument = New XmlDocument
  document.LoadXml(xmlDocument)
  Dim swriter As StringWriter = New StringWriter
  Dim writer As XmlTextWriter = New XmlTextWriter(swriter)
  xslt.Transform(document, Nothing, writer, Nothing)
  System.Diagnostics.Trace.Write(swriter.ToString())
End Sub
ファイルを使用せずにXML文書をXSLTにより処理するサンプル・プログラム(VB.NET版/C#版のアーカイブ・ファイル

 これを実行すると以下のようになる。

<result>間宮林蔵</result>
実行結果

 ここで重要なのは、XslTransformクラスに対して処理対象を指定する方法として、XmlTextReaderやXmlTextWriterクラスを利用している点である(これらのクラスの詳細については、この連載の2回目で解説しているのでそれを参照)。そして、これらのクラスはコンストラクタで指定することで、TextReader/TextWriterクラスに対して入出力できることをクラス・ライブラリのリファレンス・マニュアルで確認してみよう。あと、知るべきことは1つである。StringReader/StringWriterクラスはTextReader/TextWriterクラスを継承しているということである。

 これらの情報を複合して使えば、XslTransformクラスに対して文字列を入出力対象とすることも容易である。まず、Loadメソッドを見てみよう。これの第1引数には、XmlTextReaderクラスのインスタンスを作成して渡している。その際、引数にはStringReaderクラスのインスタンスを作成して渡している。その引数には、入力させたいXSLTスクリプトを含む文字列が指定されている。余談だが、ここで使用しているLoadメソッドには、あと2つの引数があり、それぞれ、Nothing(C#ではnull)が指定されている。これらの役割は何だろうか。まず、第2引数はすでに説明したXmlResolverを指定するものである。次に第3引数は、証拠(evidence)を指定するために使われる。これについては後で述べる。

 さて、次はTransformメソッドであるが、これに指定する処理対象のXML文書は、XmlTextReaderで渡すことはできない。ここで処理対象のXML文書は、IXPathNavigableインターフェイスを実装したオブジェクトを渡すことで指定される。そう書くと何やら面倒で複雑に思えるかもしれないが、実はDOMのXML文書オブジェクト(XmlDocumentクラス)はそれを実装しているので、それを渡すだけでよい。DOMで文字列からXML文書を読み込むのは、LoadXmlメソッドである。出力の方は、第3引数にXmlTextWriterクラスのインスタンスを指定することで、それを経由して結果を受け取ることができる。結果の文字列を取り出すには、StringWriterクラスのインスタンスにToStringメソッドを使えばよい。

 ここで気になるのは、Nothing(C#ではnull)を指定したTransformメソッドの第2引数と第4引数である。第2引数は引数のリストを渡すために使用される。第4引数はすでに述べたXmlResolverを指定するために使われるものである。

 なお、結果にXML宣言が付いていないのは、文字列に出力することが間接的に影響していると思われるが、クラス・ライブラリ内部の動作のことなので完全に理由は分からない。しかし、XML宣言が付いていないとしても、正しいXML文書であることに変わりはない。


 INDEX
  .NETで簡単XML
  第6回 .NETプログラムでXSLTスクリプトを使う
    1.XSLTとは何か
    2.XSLTミニ入門その1 要素に対応する出力
    3.XSLTミニ入門その2、3 属性に対応する出力/XPath式の値を出力
  4.プログラムでXSLTを処理/プログラム内のデータを変換
    5.XPathDocumentで処理を高速化/XSLTにプログラムを埋め込む
 
インデックス・ページヘ  「連載 :.NETで簡単XML」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間