2007年 09月 18日

xh2rdf.xsl でプロパティにクラスをつっこみたい。

なんか用語が正しくない気がするけど、あとで調べる。(とかいって調べないんだろうなぁ……)
なにをやりたいかっていうと

<div class="foaf.maker">
	<address class="foaf.Person">
		by <a href="http://www.lowreal.net/" class="foaf.website">
			<img src="http://www.lowreal.net/images/lowreal.net-logo-white1.gif" alt="lowreal.net"/>
		</a>
		<span class="foaf.name">佐藤広央</span>

		<a href="mailto:cho45@lowreal.net" class="foaf.mbox">cho45@lowreal.net</a>
	</address>
</div>

っていう断片は、

    <http://xmlns.com/foaf/0.1/maker> [
        a <http://xmlns.com/foaf/0.1/Person>;
        <http://xmlns.com/foaf/0.1/website> <http://www.lowreal.net/>;
        <http://xmlns.com/foaf/0.1/name> "佐藤広央";
        <http://xmlns.com/foaf/0.1/mbox> <mailto:cho45@lowreal.net>
    ] .

として欲しいわけですよ。

でも xh2rdf.xsl は、@href がなければプロパティノードをリテラル扱いして文字列にしてしまうので、うまくいかない。
XSLT は一個修正するといろんなところで影響でそうであんま書きかえたくないんだけど、以下のようなパッチを書いてみた。

--- xh2rdf.xsl.orig	2007-09-18 01:49:17.000000000 +0900
+++ xh2rdf.xsl	2007-09-18 01:54:56.000000000 +0900
@@ -1,4 +1,3 @@
-<?xml-stylesheet href="/parts/xsltdoc.xsl" type="text/xsl" media="screen"?>
 <!DOCTYPE xsl:stylesheet [
 <!ENTITY classnames "concat('|',@class,'|')">
 <!ENTITY localnames "concat('|',local-name(),'|')">
@@ -725,7 +724,19 @@
   <xsl:if test="@xml:lang">
    <xsl:attribute name="xml:lang"><xsl:value-of select="@xml:lang"/></xsl:attribute>
   </xsl:if>
+  <xsl:variable name="propclass" select=".//h:*[
+   contains(&blockelt;, &localnames;) and
+   contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', substring(@class,substring-after(@class, '.'),1))]"/>
   <xsl:choose>
+   <!--@ __ typed node in child element (子要素にクラスっぽいのがあればそれをプロパティの値に。
+    ただし複数の @class には対応していない) -->
+   <xsl:when test="$propclass">
+    <xsl:for-each select="$propclass"> <!-- カレントノードの変更 -->
+     <xsl:call-template name="gen-class-elt">
+      <xsl:with-param name="c" select="@class"/>
+     </xsl:call-template>
+    </xsl:for-each>
+   </xsl:when>
    <!--@ __ if no @href, a literal property (@hrefがないときはリテラルプロパティ、@hrefがあれば、さらにノード要素/属性も生成する。). -->
    <xsl:when test="not(@href)">
     <xsl:call-template name="get-label"/>

これで一応少くとも上で書いたような XHTML は期待する RDF にできた。

自分のところに XSLT おきたくなかったのに、結局読んでると書きかえたくなる罠。GPL って再配布するときどうすればいいんだっけ……条項添付したりしないといけないよなぁ。あとこの XSLT 自体にもメタデータがあって、ライセンス明示があるんだけど、GPL って書きかえた場合なんか署名に修正が必要なんだっけ……

実際こんな変態的な埋め込みするくらいなら、

<a href="foaf への URI" class="foaf.maker">...</a>

とだけ書いて、リンク先に foaf を書いたほうがいいよなぁ。でも一個先にあるのはまたリクエスト増えていやな感じもする。