PHPでXSLT関数を使ってXHTMLを出力するときのテクニック

ページ情報
制作日
2003-12-27
最終更新日
2003-12-27
参照用URI
http://www.arielworks.net/articles/2003/1227a
分野
ページ内目次

<foobar/>みたいに空要素の最後のスラッシュの前に半角スペースが入らないんですが。

XSLTの属性などではどうにも出来ません。処理が終わった後のデータをこんな感じで置換しましょう。/>の前が半角スペース以外だったら半角スペースを足してあげます。

$data = preg_replace( "/(<.*?[^ ])\/>/is", "$1 />", $data );

ねこめしにっきの記事によるとmethod="xhtml"という手もあるそうですが、XSLT2.0らしいのでPHPが使用するSablotronライブラリだと使うことが出来ません。

indent="yes"にしても綺麗にインデントされない。なんか中途半端になる。

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

「ほぼXHTMLなXML文章にしておいて特定の要素だけ書いて後はコピーで済ませよう」と思ってこの方式でノードをコピーしまくる場合(このサイトがそうです)空白が保持されれます。

<xsl:strip-space elements="*"/>

で不必要な空白文字を飛ばしましょう。ただし、pre要素を使う時はインデントされるとタブが入ってしまうので注意。

じゃぁpre要素つかえないじゃないですか。

XSLTだけで解決する方法が思いつきませんでした。xml:space="preserve"とか使ってみたんですが、なんかうまくいかない……。

$data = preg_replace( "/<pre>\s*/is", '<pre>', $data );
$data = preg_replace( "/\s*<\/pre>/is", '</pre>', $data );

やはり処理後のデータを置換するしかないようです。preタブの前後の空白文字を飛ばしてしまいましょう。

ところで、要素の中身が空の時<div/>みたいになってしまうのですが。

<xsl:if test="./@hoge">のような感じで中身があるときだけ書き出すようにしましょう。

$data = preg_replace( "/<(?!(br|hr))\S*? ?\/>/", "", $data );

XHTMLでは属性を1つも持たない空要素はbrhrだけなので、このように書いておけば一応消すことは出来ます。が、お勧めはしません。

連絡先、リンク、転載や複製などについては「サイト案内」をご覧ください。Powered by HIMMEL