- - PR -
XSLT/XPathについての質問
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2002-03-01 12:59
初めてお便りします。
会議室というものに初めて参加するので、無礼なところがありましたらご指摘願います。 さて、早速ですが、XSLT/XPathについて3つほど質問させてください。 質問@ XSLT/XPathで、テキストノードに含まれる特定の文字列を要素に変換することができますか? 例えば、 <div>ああああXMLあああXMLああ</div>を <div>ああああ<span>XML</span>あああ<span>XML</span>ああ</div> のような形にしたいのですが...。 ノード内に変換対象がひとつだけなら、 contain()とsubstring-after()/before()の組み合わせでできそうですが、 対象が複数ある場合はどうすればよいのでしょうか。 A なぜtranslate()は変換元・先の文字列長が同じものしか変換してくれないのでしょうか? B そもそもテキストノードの中身を加工するというのは、XSLTの思想に反するのですか? では、よろしく回答願います。 以上 |
|
投稿日時: 2002-03-01 14:21
A なぜtranslate()は変換元・先の文字列長が同じものしか変換してくれないのでしょうか?
「文字列置換」でなく「文字置換」だから。a→x,b→y を "ab","xy" と指定 B そもそもテキストノードの中身を加工するというのは、XSLTの思想に反するのですか? XSLT仕様の前書きにその様に書かれています。(初期想定は、目次・索引が作れればOK) しかし、XSLTは最初に人々の前に出現した XMLのスクリプトで、標準にもなったので 限界を試すかのように使われることも多いです。クエリーにも使える(問い合わせ、更新) しかし、無理はいけません、アルゴリズムを導入して効率を追求すると XSLT の読みやすさが台なしになります。(最初からDOMで書くの以上に変になる) (大昔 Prolog でも同様の現象が起きました) XPath は大変便利で テキスト対正規表現操作(gオプション付) に XML構造対XPath操作 にあたります。text()ノードの中の操作は拡張関数やスクリプト呼び出しの 分担では(そうしないとXSLTの汎用肥大化になるでしょう) [ メッセージ編集済み 編集者: MMX 編集日時 2002-03-09 12:04 ] |
|
投稿日時: 2002-03-01 16:27
早速のご回答ありがとうございます。
確かに、テキスト処理の拡充は仕様の肥大化につながりますね。 自分としては、なにもかもXSLT/XPathで一発で変換してしまいたかったのですが、 ここは一段かましてPerlなどで加工すると言うことでしょうか。 (@はできないということですよね?) でもtranslate()の文字置換というのは文字列置換よりも需要が あるのでしょうか?それとも文字置換しかできないような制限が 何かあるのですか? |
|
投稿日時: 2002-03-01 17:13
--ここは一段かましてPerlなどで加工すると言うことでしょうか。
現在はそうと、思います。 XSLT/XPath に 「正規表現pattern」を、 の声は強いのですが。 1.の課題は テキストからxml を起こす、という境界線のとこです (xml世界の内側で動く XSLTの範囲か?) DOM(2?3?) では Range 関係のメソッドなら簡単にできるでしょう。 たとえ、文字列置換ができても、ただちに更新された テキストが部分再パースされて、XMLの構造が更新される とはならないでしょう。 XSLTの出力結果は <span> ではなく & lt;span& gt; が想定される動作。 XML的には文字列操作を自由にされると、グチャグチャに なりやすいかも。 もしXML が &XML; と書かれていたなら, DTDを読めるソフトを使い 展開済みテキストを出力できます。 DTDにエンティティ宣言を付けて XSLTで恒等変換とか (やってみないと、わかりませんが)、 SGMLのタグ・ノーマライズ&エンティティ展開のUTILソフトとかで。 エンティティは辞書を使う変換なので、直接ポイントの XInclude より 可変度が高い。 読みやすさや、処理速度に目をつむれば、できます。 --------------------------------------------------- <?xml version="1.0" encoding="Shift_JIS"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="x">XML</xsl:param><!-- 内容は定数 --> <xsl:param name="y"><span><xsl:value-of select="$x"/></span></xsl:param> <xsl:template match="/"> <xsl:apply-templates select="*"/> </xsl:template> <!-- div 中には 要素が入っていないと仮定して --> <xsl:template match="div"> <xsl:copy> <xsl:call-template name="divspan"/> </xsl:copy> </xsl:template> <xsl:template name="divspan"> <xsl:param select="string(.)" name="cdr"/> <xsl:choose> <xsl:when test="contains($cdr,$x)"> <xsl:value-of select="substring-before($cdr,$x)"/> <xsl:copy-of select="$y"/> <xsl:call-template name="divspan"> <xsl:with-param select="substring-after($cdr,$x)" name="cdr"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$cdr"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> --------------------------------------------------- もう一つの書き方は、apply-templates を mode で状態分けして matchを切り替える方法でしょう。要素混在の扱いはこちらが やりやすいかも。 [ メッセージ編集済み 編集者: MMX 編集日時 2002-03-02 01:24 ] |
|
投稿日時: 2002-03-04 21:00
名前付きテンプレートにして再帰的に呼び出すという方法ですね。
これだとsubstring-after()で切り出した文字列を、 テキストの終りが来るまで次々に変換対象にできますね。 なるほど、ためになりました。早速試してみます。 混在要素や、変換対象の文字列が複数種類ある場合のテンプレート についてもこれをもとにして考えてみます。 どうもありがとうございました。 |
1