Index > XPath で指定した特定部分だけをXML文書から抜き出すスタイルシート
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
 Twitter
follow me on Twitter
 Categories