- PR -

固定幅、右揃えの文字列を出力したい

1
投稿者投稿内容
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-13 12:22
いつもお世話になっております、
koaraと申します。

MSXML3
で、

sample.xml:

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
<s:AttributeType name="MACHINE" rs:number="1" rs:nullable="true" rs:write="true">
<s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/>
</s:AttributeType>
<s:AttributeType name="PARTS_NO" rs:number="2" rs:nullable="true" rs:write="true">
<s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/>
</s:AttributeType>
<s:AttributeType name="STATUS" rs:number="3" rs:nullable="true" rs:write="true">
<s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/>
</s:AttributeType>
<s:AttributeType name="STOCK_NUM" rs:number="3" rs:nullable="true" rs:write="true">
<s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/>
</s:AttributeType>
<s:AttributeType name="INTIME" rs:number="3" rs:nullable="true" rs:write="true">
<s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/>
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row MACHINE="APPLE" PARTS_NO="1" STATUS="WAIT" STOCK_NUM="4" INTIME="2005/09/09 12:33:11"/>
<z:row MACHINE="DELL" PARTS_NO="2" STATUS="ENOUGH" STOCK_NUM="43" INTIME="2005/09/05 11:13:12"/>
<z:row MACHINE="NEC" PARTS_NO="3" STATUS="EMPTY" STOCK_NUM="1" INTIME="2005/09/09 02:03:01"/>
<z:row MACHINE="HP" PARTS_NO="4" STATUS="WAIT" STOCK_NUM="3" INTIME="2005/03/09 11:32:31"/>
</rs:data>
</xml>

というxmlを

sample.xsl:

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xml:space="default" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:for-each select="//z:row">
<xsl:value-of select="format-number(@STOCK_NUM,####" /><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

というxslを使ってSTOCK_NUM属性を4桁の固定幅で右揃えして出力したいです。

期待している結果は
コード:

4
43
1
3


なのですが、うまくいきません。

もう何日も苦戦しておりどうにも困っております。
皆様のお力を拝借させて頂きたくスレを立てさせて頂きました。
アドバイスよろしくお願いします。


[ メッセージ編集済み 編集者: koara 編集日時 2005-10-13 16:23 ]
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-10-13 14:01
) 対応カッコはどこ?
>もう何日も苦戦しておりどうにも困っております。
自身のプログラマ適性に疑問を持ったほうが、いいかも

[ メッセージ編集済み 編集者: MMX 編集日時 2005-10-13 14:22 ]
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-13 14:23
MMX様
ありがとうございます。

すみません、見落としていました。
編集中に間違えて消してしまったようです。

実際は
引用:

<xsl:value-of select="format-number(@STOCK_NUM,####" />


ではなく
<xsl:value-of select="format-number(@STOCK_NUM,'####')" />
となっております。

>自身のプログラマ適性に疑問を持ったほうが、いいかも
厳しいお言葉ですが、真摯に受け止めて勉強していきます。

[ メッセージ編集済み 編集者: koara 編集日時 2005-10-13 14:27 ]

[ メッセージ編集済み 編集者: koara 編集日時 2005-10-13 20:34 ]
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-10-13 18:33
エラーメッセージを読めていませんね、実行した?

クエリー文字列に予期されない文字列が含まれています。
format-number(@STOCK_NUM,-->#<--###)
と 表示が出ます
'####'
が正解

と言うか

XSLT format-number(
で検索すると そのソースサンプルですぐ わかります

いつもコピペで、ソースを代芽内君と会話した気分
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-13 20:30
MMX様 
大変恐縮なのですが、WEBページをコピペで投稿してません。
実際使っているソースから質問の意図する部分だけを抽出している途中に間違えたのだと思います。

引用:

XSLT format-number(
で検索すると そのソースサンプルですぐ わかります


たのしいXMLは分かり易いのでいつも参考にさせて頂いています。

質問者として投稿したソースをしっかりしなかった点は申し訳なかったです。
早速直しました、今後は気を付けます。

引用:

いつもコピペで、ソースを代芽内君と会話した気分



@ITクラブ Cafe 会議室
件名:返答者の心得と技術
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=24405&forum=3&142

質問者のくせにこんなことを言ってはいけないのかもしれませんが、
いろんな考えの方がいらっしゃいますよ。
こういう方のお陰で問題を解決できています、感謝しています。
それに質問者の'ぬし'にならないよう返答者としても投稿できるようになりたいと思っています。


[ メッセージ編集済み 編集者: koara 編集日時 2005-10-13 20:33 ]

[ メッセージ編集済み 編集者: koara 編集日時 2005-10-13 20:35 ]
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-10-14 01:30
動くxsltになったところで、話は次に進みます

ゼロサプレスしない10進固定桁では
'0000'

リーディングゼロを空白で詰めるには
<xsl:value-of select="concat(substring(' ',1, 4 - string-length(@STOCK_NUM)) ,@STOCK_NUM)"/>
かな? ' ' 内の空白は多めにします。

固定長文字列の考え方の無い世界なので、
固定長や右寄せを無理して作るには 手間がかかります。
xsltの言語設計は、濃い文字列処理対応ではありません。
よって、XSLT2.0 で機能強化に力を注ぐ人々は多い。

XSLT 固定長
で検索すると、たとえば

EXSLT.NET を使用して実用的なソリューションを構築する
http://www.microsoft.com/japan/msdn/library/ja/jpdnxml/htm/practexslt.asp
str:padding 関数
が見えます。

[ メッセージ編集済み 編集者: MMX 編集日時 2005-10-14 10:07 ]
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-14 15:21
MMX様
ありがとうございます、お返事頂けたこと正直驚いています。
それと同時に少し恥ずかしい気持ちになりました。

というのも、投稿する前にconcat,substringでいけそうだなと思っていたにも関わらず、
丸投げしてしまいました。
自分でできる範囲での答えを提示するべきだったと思います。
そういった行動ができていれば変な誤解をまねくこともなかったと反省しております。

ひとつ言い訳をさせて頂けるならXMLというものの勝手なイメージがあり
簡単に固定長や右寄せ等の文字列処理もできるだろうと思ってしまいました。

確かに言われてみると、関数郡は貧弱だと思います。

引用:

XSLT 固定長
で検索すると、たとえば

EXSLT.NET を使用して実用的なソリューションを構築する
http://www.microsoft.com/japan/msdn/library/ja/jpdnxml/htm/practexslt.asp
str:padding 関数
が見えます。



皆さんはこういうところを読んで知識をつけているんですね。

引用:

XSLTの勧告は拡張機能の実装を実現するメカニズムの定義がなく、XSLTプロセッサのベンダ任せになっている


多少の拡張はXSLTプロセッサ側も出来るようなら、更に使い勝手が良くなる気がします。

最後に結果ですが、
<xsl:value-of select="concat(substring(' ',1,7-string-length(@STOCK_NUM)),@STOCK_NUM)" />
とすることで、無事7桁の固定長右揃えの文字列に変換することができました。

ありがとうございました。

1

スキルアップ/キャリアアップ(JOB@IT)