- - PR -
空白文字で区切られた要素から文字列を抜き出したい。
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2004-11-08 13:26
どなたか教えてください。
xmlの要素の中に空白文字で区切られたデータがあるとします。 <youbi>getsu ka sui moku kin do nichi</youbi> この要素から、3番目の要素suiをxslで抜き出したいのですが、 方法が見つかりません。 要素に入る文字列の長さが決まっていれば、 substring 関数で9文字目から3文字抜き出すこともできますが、 要素の中に入るデータが多い場合を考えると使えません。 そもそも、それぞれを要素に区切るべきなのかも知れませんが・・・。 見たことがありませんが、格子点データなどをxml化した場合などは 同じような問題が発生すると思われます。 ご存知のかた、お願いいたします。 |
|
投稿日時: 2004-11-08 13:40
XML 関連のAPI には 「サブパーサー」のようなものはありません。
文字列全体を取り出し、伝統的なテキスト処理を行います。 それが、正規表現での切り出しとか tokenize のように軽いものか 各種パーサージェネレータを使うようなものになるかは、文法しだい。 SGMLパーサーなら データタグとか言って 文字列パターンをタグ扱い することができます。(日本語文書はまず見つからない) 例 O'Reilly Book Hacking XML Hack #94, http://www.xml.com/lpt/a/2004/09/15/XMLHacks.html 本の紹介ページから、サンプルで使ったソースダウンロード へのリンクが探せます。OpenSP1.5 でも動きました。 >格子点データなどをxml化した場合などは 同じような問題が発生すると思われます。 Bio の遺伝子情報の交換では バイナリの ASN.1 を使う場合もあります。 使用予定のモジュールで、XPath2.0 の関数 が先行実装されていないか、確認してみましょう http://www.w3.org/TR/xquery-operators/#regex-syntax [ メッセージ編集済み 編集者: MMX 編集日時 2004-11-08 14:58 ] |
|
投稿日時: 2004-11-10 11:47
tokenize あるいは split に類する操作は,再帰テンプレートで実現します。あちこちのFAQに実例があるでしょう。
tokenのX番目を取り出すには, 手順1 tokenizeの結果を変数にセットする 手順2 その変数のノードセットとして扱い,X番目の子要素を取り出す。 注意するのは,変数をノードセットとして操作する方法が,XSLTエンジンによって異なることです。 saxonはxsl version1.1に準拠していますから, "$変数名"でノードセットとして扱えます。 MSXMLは,拡張関数node-set($変数名)を使って,ノードセットに変換します。 XALANは,どうだったか,忘れてしまいました。ごめんなさい。 XMLが下の形だとすると <root> <youbi>getsu ka sui moku kin do nichi</youbi> </root> 3番目を取り出すスタイルシートはこのとおり。 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:variable name="data-set"> <xsl:apply-templates/> </xsl:variable> <data> <xsl:value-of select="$data-set/*[3]"/> </data> </xsl:template> <xsl:template match="youbi"> <xsl:call-template name="tokenize"> <xsl:with-param name="str" select="normalize-space(.)"/> </xsl:call-template> </xsl:template> <xsl:template name="tokenize"> <xsl:param name="str"/> <xsl:choose> <xsl:when test="contains($str, ' ')"> <token> <xsl:value-of select="substring-before($str, ' ')"/> </token> <xsl:call-template name="tokenize"> <xsl:with-param name="str" select="substring-after($str, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <token><xsl:value-of select="$str"/></token> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> [ メッセージ編集済み 編集者: バクシ 編集日時 2004-11-10 11:52 ] |
|
投稿日時: 2004-11-10 14:57
XSLT1.0において、仕様外の拡張関数などは使わずに、3番目だけを取り出すスタイルシートは以下のとおりです。
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="junban" select="3" /> <xsl:variable name="kugiri" select="' '" /> <xsl:template match="youbi"> <xsl:call-template name="takeout"> <xsl:with-param name="str" select="normalize-space(.)"/> <xsl:with-param name="num" select="$junban"/> </xsl:call-template> </xsl:template> <xsl:template name="takeout"> <xsl:param name="str"/> <xsl:param name="num"/> <xsl:variable name="num1" select="$num - 1"/> <xsl:variable name="car" select="substring-before($str, $kugiri)"/> <xsl:variable name="cdr" select="substring-after($str, $kugiri)"/> <xsl:choose> <xsl:when test="$num1 = 0"> <xsl:value-of select="$car" /> </xsl:when> <xsl:otherwise> <xsl:call-template name="takeout"> <xsl:with-param name="str" select="$cdr"/> <xsl:with-param name="num" select="$num1"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> |
|
投稿日時: 2004-11-11 08:57
XSLT2.0 XPath2.0 を実装した saxon7(http://www.saxonica.com)を使えば、
tokenize()関数を使って <xsl:value-of select="tokenize(normalize-space(//youbi), ' ')[3]"/> で、"sui"を取り出せます。あっけないこと、今まで再帰テンプレートを使って頭をひねっていたのが馬鹿馬鹿しくなります。tokenize()関数の二つ目の引き数には,正規表現が使えます。 tokenize()関数の結果は、<xsl:for-each>で操作することも可能。 <xsl:for-each select="tokenize(normalize-space(//youbi), ' ')"> <xsl:if test="position()=3"> <xsl:value-of select="."/> </xsl:if> </xsl:for-each> は、上の<xsl:value-of>要素と同じ結果になります。 |
|
投稿日時: 2004-11-13 12:44
バクシ様、こんにちは。
>XALANは,どうだったか,忘れてしまいました。ごめんなさい。 私も興味を持って調べてみました。 http://www.xml.com/pub/a/2003/07/16/nodeset.html#tab.namespaces を見てみたら、ほとんどのメジャーな実装で大丈夫のようですね。 私は今までMSXMLで使えることを知らずに苦労していたので、これはありがたいです。 まあ何にせよ、XSLT 2.0が待ち遠しいというところです。 |
|
投稿日時: 2004-11-22 23:04
皆様、詳しい返答ありがとうございました。
まだ勉強中な為、十分な理解をするのに時間がかかっており、 お礼の言葉が遅くなったことをお詫びいたします。 今回の例では、TAKABEさまの例がとても参考になりました。 というのは、 私の基本線は、多くの方に使っていただくスタイルシートを作ることにあるためです。 素人とまでは行きませんが、普通の人が手間なく使用できる環境が望ましい。 で、 xsltによる変換・出力には、さまざまなパーサー?エンジン?があり、 どれを使うかについても、 xsltのバージョンについても 一番広くなじまれている方法を取りたいと考えています。 xmlを変換する上で、どの方法が効果的かどうか、さらに勉強したいと思っています。 MMXさま バクシさま のアドバイスも大変参考になりました。 今やってみたいスタイルシートには、さらに疑問点がありますが、 内容が異なるので、別スレッドで質問することとします。 皆様 ありがとうございました。 |
1