VB6にてXML内に2バイト文字があるとパースできない

解決


ぬかまち  2007-07-25 04:40:35  No: 99231

現在、VB6にてMSXMLにてXMLをCGIにPOSTし、レスポンスされるXMLを処理するコードを書いています。

レスポンスされるXML内に2バイト文字が含まれていると、かならずエラーを起こしています。

レスポンスに対するXMLを処理するのに以下のように書いております。

Dim XMLDocument As MSXML2.DOMDocument50
Dim xmlTarget As IXMLDOMElement

Set XMLDocument = New MSXML2.DOMDocument50
XMLDocument.async = False

XMLDocument.loadXML (oHttp.responseText)

    Set xmlTarget = XMLDocument.selectSingleNode("//Command")
    If Not xmlTarget Is Nothing And xmlTarget.hasChildNodes() Then
        Debug.Print xmlTarget.childNodes(0).Text
    End If

いろいろ略していますが、流れはこんな感じです。
2バイト文字が含まれていると、mlTargetはNothingになってしまうし
xmlTarget.hasChildNodes()は「オブジェクト変数または・・・・」と
いわれてしまいます。

お知恵を拝借できればと思います。


魔界の仮面弁士  2007-07-25 05:25:52  No: 99232

> レスポンスされるXML内に2バイト文字が含まれていると、かならずエラーを起こしています。
・具体的には、どんな文字ですか?
・サーバ側が返す Content-Type ヘッダの内容は?

ちなみに responseText プロパティは、サーバ側に Unicode を要求します。
(デフォルトは UTF-8 です。他の UCS-2/UCS-4 も使えますけれども)

> XMLDocument.loadXML (oHttp.responseText)
responseText を loadXML するぐらいなら、最初から
responseXML を使った方が手っ取り早いのでは無いでしょうか。

responseXML プロパティ … XMLドキュメント
responseText プロパティ … 文字列
responseStream プロパティ … IStream インターフェイス
responseBody プロパティ … Byte 配列

どうしても文字化けが発生するなら、responseBody から(ADODB.Stream等で)
自力エンコードするという最終手段もあります。


ぬかまち  2007-07-25 21:57:27  No: 99233

返信ありがとうございます。
XMLとHTTPは未知の領域なので、見当ハズレな事を言っていたらすみません。

>・具体的には、どんな文字ですか?
サーバーが返しているのは
<bb>aaaa</bb>
<aa>エラーが発生しました。</aa>

VB側で受け取ると
<bb>aaaa</bb>
<aa>?R?}???h?v?????s</aa>

こんな感じで、2バイト文字が入ると1バイト文字が入っている部分でさえもXMLDocument.selectSingleNodeで検索できません。

>・サーバ側が返す Content-Type ヘッダの内容は?
text/xmlです。

>responseXML を使った方が手っ取り早いのでは無いでしょうか。
「オブジェクトはこのプロパティをサポートしてません」と言われてしまいました・・・

やりたい事としては、2バイト文字の部分はVB側では処理する必要がないので、2バイト文字が含まれていても、他の部分がちゃんと検索できれば問題ないのです。


魔界の仮面弁士  2007-07-25 23:01:39  No: 99234

> <bb>aaaa</bb>
> <aa>エラーが発生しました。</aa>
掲示板に投稿する際に、内容を省略されているのでしょうか?
見た感じ、そもそも XML の文法になっていないように思えますけれども…。

loadXML で読み込んであるのであれば、loadXML の戻り値、
および parseError が返すエラー理由を確認してみてください。

あと、これらのエンコーディングは何ですか? デフォルトの UTF-8 だとすれば、
2 バイト文字といえば「αβγ」等で、「あいう」等は 3バイト文字ですよね。

# VB 標準の UTF-16 だとすれば、もともと 2 バイト固定なので、
# あえて「2バイト文字」という表現は使わないでしょうし。

> text/xmlです。
charset は無いのですね。
その場合、responseText は UTF-8 として処理した結果を String で返すはずです。
BOM があればそれが考慮されますが、<?xml encoding での指定は解釈されません。

> 「オブジェクトはこのプロパティをサポートしてません」と言われてしまいました・・・
(Set ではなく) Let の方で responseXML プロパティを読み取ろうとしていませんか?

> 2バイト文字が含まれていても、他の部分がちゃんと検索できれば問題ないのです。
そのために、サーバ側で対処するべきことは、
・<?xml encoding の指定の有無を確認。有るなら、encodingの内容を確認。無いなら UTF-8 扱い。
・HTTP レスポンスの実際のバイナリは、その encoding 指定と一致しているか確認。特に BOM の有無。
・HTTP ヘッダで、Content-Type の charset も指定。
ですね。これらの情報が間違っているなら、クライアント側で足掻いても仕方ありませんし。

あるいは……サーバが間違っている場合に、VB 側で強制的に辻褄袷をする方法については、
すでに回答済みですから、こちらは問題ないでしょう。
>>> 自力エンコードするという最終手段もあります。


魔界の仮面弁士  2007-07-25 23:10:53  No: 99235

間違い。

>>> 自力エンコード
受信側なので、(エンコードではなく)デコードですね。m(_ _)m


ぬかまち  2007-07-26 01:01:17  No: 99236

いろいろとありがとうございました。
お客のセキュリティチェックが厳しいため、かなり省略した記述をしたことをお許しください。

結局のところ、
XMLDocument.loadXML (oHttp.responseText)

XMLDocument.loadXML (StrConv(oHttp.responseBody, vbUnicode))
こうすることで解決はしました。

responseXMLは、やはりサポート外と言われるだけで・・・

正直、ほとんど理解していないままの解決で、ソースもとてもお見せできる
物じゃありません・・・
スキルアップに励みます。


魔界の仮面弁士  2007-07-26 01:21:59  No: 99237

> XMLDocument.loadXML (StrConv(oHttp.responseBody, vbUnicode))
> こうすることで解決はしました。
Shift_JIS なのですね。では、レスポンスの先頭に、
<?xml version="1.0" encoding="Shift_JIS"?>
は含まれているのでしょうか? 含まれていないなら

> responseXMLは、やはりサポート外と言われるだけで・・・
responseXML の使い方が間違っていた、ということはありませんか?
Shift_JIS な XML を返すサイトを使って試しましたが、当方では、
  Set XMLDocument = oHttp.responseXML
で動作したのですけれども。

-----------
Dim oHTTP As MSXML2.IServerXMLHTTPRequest
Set oHTTP = New MSXML2.ServerXMLHTTP50
oHTTP.open "GET", "http://www.mediafusion.co.jp/xmlgate/sample.xml", False
oHTTP.send

Dim XMLDocument As MSXML2.DOMDocument50
Set XMLDocument = oHTTP.responseXML


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加