Mon, August 17, 2009
XPath で指定した特定部分だけをXML文書から抜き出すスタイルシート
XML文書から XPath で指定した部分だけを抜き出したい。
XSLTではデフォルトの変換規則があるため、これが意外に難しかったのでメモ。
(デフォルト規則が分かっていれば難しいことはない。)
XPathで指定した部分を取り出したいだけならば、xpathコマンドを使えばOK.
Ubuntu などでは、apt-get install libxml-xpath-perl でインストールできます。
以下のように使えます。$ cat sample.xml | xpath -q -e "/book/chapter/title/text()"
XML文書
<?xml version="1.0" encoding="UTF-8" ?>
<book>
<chapter>
<title>hello world 1</title>
<sect1>
<title>hello world 2</title>
</sect1>
</chapter>
</book>
以下では、このXML文書から章タイトルだけを抜き出してみます。
スタイルシートその1
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/book/chapter/title/text()" >
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
章タイトルだけを抜き出すスタイルシート。 (実際にはうまくいかない)
結果
<?xml version="1.0" encoding="UTF-8"?>
hello world 1
hello world 2
これは意図していない結果です。 hello world 1だけを抜き出したいのですが、 他の部分も出力されています。
調べてみると、XSLTではデフォルト規則として、 以下のスタイルシートが暗黙に定義されているとのこと。
<xsl:template match="text()">
<xsl:value-of select="." />
</xsl:template>
スタイルシートその2(改良版)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="text()" />
<xsl:template match="/book/chapter/title/text()" >
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
章タイトルだけを抜き出すスタイルシート、改良版。 デフォルトのスタイルシートを上書きして、 テキストデータをそのまま出力するというデフォルト規則を無効にします。
結果
<?xml version="1.0" encoding="UTF-8"?>hello world 1
スタイルシートその3(完成)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="text()" />
<xsl:template match="/book/chapter/title/text()" >
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
xsl:output を追加して、XML宣言 を出力しないようにします。
結果
hello world 1