汎用っぽいテンプレ作っていたら、XSLT だけで一行ごとに l 要素とかソレっぽいのでマークアップできることに気付いた……っていうかアレだ。

<xsl:template name="split">
<xsl:param name="value"/>
<xsl:param name="splitter"/>
<xsl:param name="element-name" select="'t:item'"/>
<xsl:choose>
<xsl:when test="contains($value, $splitter)">
<xsl:element name="{$element-name}">
<xsl:value-of select="substring-before($value, $splitter)"/>
</xsl:element>
<xsl:call-template name="split">
<xsl:with-param name="value" select="substring-after($value, $splitter)"/>
<xsl:with-param name="splitter" select="$splitter"/>
<xsl:with-param name="element-name" select="$element-name"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$element-name}">
<xsl:value-of select="$value"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:call-template name="split">
<xsl:with-param name="value" select="'aaa#x0a;bbbb#x0a;cccc#x0a;z'"/>
<xsl:with-param name="splitter" select="'#x0a;'"/>
<xsl:with-param name="element-name" select="'l'"/>
</xsl:call-template>

正規表現使いたい……

  1. トップ
  2. xslt
  3. XSLT で行をマークあっぴ
  1. トップ
  2. xml
  3. XSLT で行をマークあっぴ

Opera 7.54 でコードが途中まで消えるっつう指摘を受けたので、navigator.userAgent.match(/Opera/) && navigator.userAgent.match(/7\.54/) が真だったら色づけしないようにした。消えるのは致命的杉。

たぶんドキュメントフラグメントに大量にノード突っ込んで既存のノードと置き換える部分が原因で最初のほうがレンダリングされなくなるんだと思うけどよくわからない。リロードするたびに消える範囲が変わる;

  1. トップ
  2. web
  3. Opera で色づけ

またメールが来なくなっていたので確認。インデクシングされていない。NMZ.lock2 は最初なかったのに、CGI 経由で実行したらNMZ.lock2 が残っていますというエラーとともに出来た。自分で作って自分でえらー吐いてるのか……?

仕方ないのでまたインデックス全部削除。

  1. トップ
  2. web
  3. Namazu Cron

ネームスペース宣言の集合は、式が現れるアトリビュートを持つエレメントのスコープに含まれるものと同じである。この集合には、XML ネームスペース勧告 (XML Namespaces Recommendation) [XML Names] が必要とする、暗黙的に示されたプレフィックス xml の宣言も含まれる。デフォルトのネームスペース (xmlns を用いて宣言されたもの) は、この集合の一部ではない。 とか書いてあったりする。ソースツリーのデフォルトネームスペース URI が null (特に名前空間を全く宣言していない場合とか) 以外の時は絶対にプリフィックス無しではマッチとかしない。

<foo>
<bar>baz</bar>
</foo>

この場合に string(/foo/bar) = 'baz' は true。

<foo xmlns="http://foo/">
<bar>baz</bar>
</foo>

この場合は string(/foo/bar) = 'baz' は false。/foo/bar は何も選択しない。例え XSLT 側のデフォルト名前空間が http://foo/ であっても何も選択されないxmlns:f="http://foo/" とかやって /f:foo/f:bar ってやらなきゃいけない。

で、困るっていうかよくわからんのはソースツリーのデフォルトネームスペースと結果ツリーのデフォルトネームスペースを同じにしたいときなんですよと。必然的に xmlns:f="http://foo/"xmlns="http://foo/" とか (順番も重要) やるわけですよ。exclude-result-prefixes="f" とかやるわけですよ。そうすると仕様書的に正しいかはよくわからないけど Sablotron の場合はどっちとも (xmlns, xmlns:f) 消えるんですよ (msxsl では大丈夫)。で、どうすんねんと哀さんと話していた次第(謎

xsl:namespace-alias とか利用すんのかなぁと思っていくつかソレっぽく書いてみたけどダメだった……なんかセオリー的なやり方ってないのかな。

  1. トップ
  2. web
  3. XSLT の XPath の
  1. トップ
  2. xml
  3. XSLT の XPath の
  1. トップ
  2. xslt
  3. XSLT の XPath の
  1. トップ
  2. xpath
  3. XSLT の XPath の

XSLT では属性ノードとその親ノード (要素) との関係は片方向……属性ノード側からは @attr[. = ../../@attr] (省略しない場合: attribute::attr[self::node() = parent::node()/parent::node()/attribute::attr])) とかいう風に親がちゃんと親に見える (っておかしいな) けど、その親からは (attribute:: としているように) 軸が違う。ここで親から child::attr とアクセスできたら困るわけだけど、ややこしい。どうも俺は属性を子ノード的にイメージしていて attribute っていう軸がイメージしにくい。

DOM の場合は属性に親ノードはなく (parentNode は null) ownerElement に親要素が入ってる。軸が完全に分離してるっつうのかなぁ。DOM だとあんまり混乱しない。ただのプロパティでしかないからかなぁ。

XSLT の場合も DOM っぽい考え方をすればいい気がするのでちゃんと書いて、どこがどう違うかを考えてみてる。軸をプロパティと考えればいいの鴨。

// わけわかんコードだ(w
contextNode = current();
with (contextNode) {
contextNode = child["*"];
with (contextNode) {
contextNode = attribute["attr"];
with (contextNode) {
text();
}
}
}
  1. トップ
  2. xslt
  3. XSLT と DOM との相違
  1. トップ
  2. dom
  3. XSLT と DOM との相違
  1. トップ
  2. xml
  3. XSLT と DOM との相違
  1. トップ
  2. xpath
  3. XSLT と DOM との相違