Curl Global Community
半角スペースのみのsoapレスポンスについて - Printable Version

+- Curl Global Community (https://communities.curl.com)
+-- Forum: Discussions (https://communities.curl.com/forumdisplay.php?fid=1)
+--- Forum: General Curl questions (https://communities.curl.com/forumdisplay.php?fid=2)
+--- Thread: 半角スペースのみのsoapレスポンスについて (/showthread.php?tid=223)



半角スペースのみのsoapレスポンスについて - onyo - 08-22-2011

はじめまして。

現在、Curl Ver4.0 WSDK1.0を使用した、Webシステムに携わっております。

COM.CURL.WSDK.1.0 を使用したSOAP通信にて

レスポンス値が 半角スペース 及び 改行のみのStringである場合

SOAPHTTPRPCPostCaller.call
の戻り値 responses の該当要素では
String の length が 0 になってしまいます。

パケットを監視する http監視上は 正しく受け取れているようですが、
回避策はあるのでしょうか?



RE: 半角スペースのみのsoapレスポンスについて - heavybugtracker - 08-22-2011

まだ4.0使ってるんですか?先日4.0のサポートが切れたと知ってて、あれ、時代の流れが早いなーと感心しました...


確かにXMLの仕様で、スペースと改行が無視されることができるらしく、もうしかして、これはWSDKの仕様かも知れないね、恐らくWSDKの内部実装に依存されている...WSDKのソースコードが公開されているので、ソースコードで調べてみたらどうですか?


ちらっと見ただけですが、soap/SOAPHTTP.scurlの中でSOAPHTTPRPCPostCaller.call が定義されており、
そこからread-message-from-streamというメソッドをコールし、
以下のあたりでresponsesを作っているようです。

let (responses:{Array-of any},
headers:#{Array-of any},
header-roles:#{Array-of #String},
header-must-understands:#{Array-of bool},
root-element-attributes:#{Array-of XMLAttribute}
) =
{self.message-reader.read-rpc-response
xml-input-stream,
.............
}

set responses =
{self.close-response-stream
xml-input-stream,
responses
}


そこらへんにデバッグコードを入れてみたらいかがでしょうか?





RE: 半角スペースのみのsoapレスポンスについて - ashimo - 08-22-2011

XMLにはxmlConfusedpace="preserve"が指定されていますか?


RE: 半角スペースのみのsoapレスポンスについて - onyo - 08-22-2011

heavybugtracker 様

ご返信ありがとうございます。 はい、4.0から今の今までずっと
システム上の要件が追加されても、4.0です。
ついにはサポートがきれましたが...

半角スペース△として △△△△あ△△
といったデータは問題なく受取れますが、△△△△△△といった内容は
trimされてしまうようです。

オープンソースなので、私もある程度(trim-clone などをキーに)追ってみましたが
深くはみれていません。ご指摘のあたりをもう一度追ってみます。




RE: 半角スペースのみのsoapレスポンスについて - onyo - 08-22-2011

ashimo 様

ご返信ありがとうございます。

なるほど確かにと思い
Contract.scurl の元ネタである wsdl の xml を調べてみると
xmlConfusedpace属性 の設定はありませんでした。

オープンソース上でのCurlパーサが
ご指摘の属性を解釈している可能性が高そうですね。

属性を指定して試してみます。ありがとうございました。



RE: 半角スペースのみのsoapレスポンスについて - onyo - 08-23-2011

xml に xmlConfusedpace="preserve" の定義を試してみましたが、うまくいきませんでした。



定義の仕方が間違っているのでしょうか?
それとも、WSDKの仕様でだめなのでしょうか。。。

追記です。

soap/xml-streams.scurl
を追ってみました。

下記のメソッドが、空白のみの場合
要素を空っぽにしてくれちゃってるみたいですが、
要素の中身だけ呼ばれるメソッドではないので、対処方法に苦労中です。


Code:
{method private {check-characters}:void
    {if not self.char-buffer.empty? then
        {for c in self.char-buffer do
            {if not {StreamContentHandler.white-space? c} then
                let cs:String = {self.char-buffer.to-String}
                {self.events.append
                    {XMLCharacters
                        cs,
                        xml-name-values = {self.string-to-xml-values cs}
                    }
                }
                {break}
            }
        }
        {self.char-buffer.clear}
    }
  }



RE: 半角スペースのみのsoapレスポンスについて - hokada - 08-24-2011

> 要素の中身だけ呼ばれるメソッドではないので、対処方法に苦労中です。


このメソッドが呼ばれているのはxml-streams.scurl内の4か所だけですね。


$ fgrep -r check-character code/
code/soap/xml-streams.scurl: {method private {check-characters}:void
code/soap/xml-streams.scurl: {self.check-characters}
code/soap/xml-streams.scurl: {self.check-characters}
code/soap/xml-streams.scurl: {self.check-characters}
code/soap/xml-streams.scurl: {self.check-characters}




RE: 半角スペースのみのsoapレスポンスについて - ashimo - 08-24-2011

試してみた限りここの処理では self.char-buffer には内容文字列が入ってきてました。

このソースにもXMLCharactersがありますが、
ヘルプにあるXMLCharactersの以下の記述はこのことを指しているかも?
はずしてたらすみません。
> XML ドキュメント内で XMLStartElement と XMLEndElement の間に空白文字以外のテキストが存在しない場合は、
> XMLInputStream が XMLCharacters を提供できないことがあります。



RE: 半角スペースのみのsoapレスポンスについて - onyo - 08-24-2011

SAXPaser のイベントからで、
呼ばれる契機は確かに四箇所ですが
要素が値を表すものである場合

{method public {end-element
namespace:String,
local-name:String,
q-name:String}:void

から呼ばれるようです。
そこで、以下のコードで出力を見てみました。

Code:
{method private {check-characters flg:bool = false}:void
    {if not self.char-buffer.empty? then
    {if flg then
            {output "*", self.char-buffer.empty? "*"}
        }
        {for c in self.char-buffer do
            {if not {StreamContentHandler.white-space? c} then
                let cs:String = {self.char-buffer.to-String}
                {self.events.append
                    {XMLCharacters
                        cs,
                        xml-name-values = {self.string-to-xml-values cs}
                    }
                }
                {break}
            }
        }
        {self.char-buffer.clear}
    }
}

ContentHandleクラス の end-element は
要素の終了で呼ばれるためそれが値であろうが、単なるxml記述上の改行や空白であろうが
削除してしまいます。

汎用的な改修は難しいかもしれませんが、
項目に特化するならば、local-name、
とあるxmlだけに絞るなら更に namespace を
引数に追加して、強引にスペースを返却させることは可能でした。

Code:
{method private {check-characters flg:bool = false, local-name:#String = null, namespace:#String = null}:void
    {if not self.char-buffer.empty? then
        {if flg and  namespace == "http://temp.openuri.org/Hoge/hogehoge.xsd" then
            {switch local-name
             case "hoge","hoge_hoge","hoge_desu"
                let cs:String = {self.char-buffer.to-String}
                {self.events.append
                    {XMLCharacters
                        cs,
                        xml-name-values = {self.string-to-xml-values cs}
                    }
                }
                {self.char-buffer.clear}
                {return}
            }
        }
        {for c in self.char-buffer do
            {if not {StreamContentHandler.white-space? c} then
                let cs:String = {self.char-buffer.to-String}
                {self.events.append
                    {XMLCharacters
                        cs,
                        xml-name-values = {self.string-to-xml-values cs}
                    }
                }
                {break}
            }
        }
        {self.char-buffer.clear}
    }
  }

もうちょっとうまくやれるかもしれませんね。