- PR -

Xerces-C++でtranscodeは何に変換してる?

投稿者投稿内容
Tacchang
会議室デビュー日: 2002/02/02
投稿数: 16
お住まい・勤務地: 川崎市
投稿日時: 2002-04-13 21:43
皆様はじめまして、Tacchangと申します。
XMLファイルの内容を読むプログラムを作ってみたのですが、日本語がうまくとれません。
XMLファイルはUTF-8で書かれています。
<?xml version='1.0' encoding='UTF-8'?>

そのファイルをDOMParser.parse()して、getNodeValue()で得た文字列をtranscode()してWindowsコントロールのキャプション(TEdit->Text)にセットするのですが、日本語コードが表示されません。

transcode()はどのような文字コードに変換するのでしょうか。

Shift-JISのファイルを、encoding='UTF-8'などとして、だまして読むと、これは読み込めます。
かと言って、UTF-8で書かれたファイルは読み込めません。(アルファベットok)

XercesのAPIドキュメントを読んでもtranscode()がどのようなコードを返すのか理解できません。
アドバイスをお願いいたします。

--------------
□私の環境
Xerces-C++ 1.7
Borland C++ Builder 6
Windows 2000
DOM API
Tacchang
会議室デビュー日: 2002/02/02
投稿数: 16
お住まい・勤務地: 川崎市
投稿日時: 2002-04-14 14:39
質問をさせていただいたTacchangと申します。
本件、rawBuffer()を使って解決しました。
お騒がせしました。<(_ _)>
yaz
会議室デビュー日: 2002/07/05
投稿数: 4
投稿日時: 2002-07-05 00:41
私も困っています。

いろいろなホームページを見て、みようみまねで次のようなコードを書いたのですが、
こんなXMLでも「あかさた」と表示されず「 aa」と表示されてしまいました。

MessageBoxで表示する簡単なサンプルがあれば、何とかなりそうな気がするのですが、
どんぴしゃりなものは見つけられませんでした。
アドバイスください、よろしくお願いいたします。
-----XML-----
<?xml version="1.0" encoding="Shift_JIS"?>
<Test>
あかさた
</Test>
-------------

-----test.cpp-----
// test.cpp
//
#include <windows.h>
#include <locale>
#include <string>

// Xerces
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/DOMParser.hpp>
#include <xercesc/framework/XMLFormatter.hpp>


std::string transcode(const DOMString& x) {
const wchar_t* buf = x.rawBuffer(); // UNICODEバッファと
unsigned len = x.length(); // その長さ
wchar_t* wcs = new wchar_t[len+1]; // 領域確保
char* mbs = reinterpret_cast<char*>(wcs);
*std::copy(buf, buf+len, wcs) = L'\\0'; // UNICODEバッファからコピー
XMLString::transcode(wcs, mbs, len*2+1); // nativeコードに変換
std::string ret(mbs); // std::stringを生成
delete[] wcs; // 領域解放
return ret;
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
// localeを'日本語'に設定
std::locale::global(std::locale("japanese"));

// Xercesの初期化
XMLPlatformUtils::Initialize();

// XMLをパース
{
DOMParser parser;
parser.parse("test.xml");

// ルート・エレメント(テスト)を取得
DOM_Element test = parser.getDocument().getDocumentElement();
std::s = transcode( test.getFirstChild().getNodeValue() );
MessageBox(NULL, s.c_str(), "getNodeValue", MB_OK);
}

// Xercesの後始末
XMLPlatformUtils::Terminate();

return 0;
}
Tacchang
会議室デビュー日: 2002/02/02
投稿数: 16
お住まい・勤務地: 川崎市
投稿日時: 2002-07-06 18:55
# 遅くなってしまいました。

私はtranscodeを以下のように自作しました。
それ以外は何もしていません。
yazさんがあちこちに気を配っているのを見て、あぁ、こういう配慮が必要なんだと気が付いたくらいです。(^_^;

何かの参考になれば幸いです。

--------------
AnsiString TForm1::transcode(const DOMString& str)
{
// XMLString::transcode()は何に変換しているか判らないので使わない
const wchar_t* buf = str.rawBuffer(); // UNICODEバッファと
unsigned len = str.length(); // その長さ
wchar_t* wcs = new wchar_t[len+1]; // 領域確保
// char* mbs = reinterpret_cast<char*>(wcs);
*std::copy(buf, buf+len, wcs) = L'\\0'; // UNICODEバッファからコピー
AnsiString ret = WideCharToString( wcs );
delete[] wcs; // 領域解放
return ret;
}
yaz
会議室デビュー日: 2002/07/05
投稿数: 4
投稿日時: 2002-07-07 11:45
ありがとうございます。Borland系の関数ですね > WideCharToString

TacchangさんのtranscodeはAnsiStringを返していたので、std::stringを返すように、
そしてWideCharToStringを使わないように、ちょっとアレンジしてこんな感じにしました。
ほんとは、WideCharToMultiByteを使うべきなのかもしれないのですが、使い方が
よくわからなかったので、wcstombsを使っています。
これで、うまくMessageBoxで表示できている様子です。ありがとうございました。
これではまずいぞ。など、アドバイスがありましたら、お願いします。 > みなさま

std::string transcode(const DOMString& str) {
const wchar_t* buf = str.rawBuffer(); // UNICODEバッファと
unsigned len = str.length(); // その長さ
wchar_t* wcs = new wchar_t[len+1]; // 領域確保
*std::copy(buf, buf+len, wcs) = L'\0'; // UNICODEバッファからコピー

int len2 = wcstombs(NULL, wcs, 0);
char* pstr = new char[len2+1];
if (!pstr) return NULL;

wcstombs(pstr, wcs, len2+1);

delete[] wcs; // 領域解放
std::string ret(pstr);
return ret;
}
しょむ
ぬし
会議室デビュー日: 2001/09/06
投稿数: 430
投稿日時: 2002-07-07 15:38
余計なお世話かもしれませんが、「Shift_JIS」を使っているときは「〜」「−(マイナス)」も確かめたほうがよいでしょう。
化ける場合は「Windows-31J」を使いましょう。
yaz
会議室デビュー日: 2002/07/05
投稿数: 4
投稿日時: 2002-07-07 16:09
アドバイスありがとうございます。
〜と−は、全角が化ける可能性があるということなんですね?
ちょっと試した限りでは、うまく変換されたみたいです。

今後のために教えていただきたいのですが、「Windows-31Jを使う」とおっしゃっているのは、
<?xml version="1.0" encoding="Shift_JIS"?>
の変わりに、
<?xml version="1.0" encoding="Windows-31J"?>
を使うということでしょうか?

それとも、コード中で、SJISコードに変換するのではなくWindows 3.1Jコード?に変換するということでしょうか?

少し調べた感じでは前者のように思えました。

勉強になります。ほかにも、ここはよく引っかかるポイント。というのがあればぜひ。
エントランス
会議室デビュー日: 2002/07/17
投稿数: 1
投稿日時: 2002-07-17 19:39
皆さんはじめまして。
私もxerces-cをlinux上でgcc3でコンパイルしたものを
使用して(redhat linux 7.3 + xerces-c1.6 + icu2.0)
開発を行っているのですが、XMLファイル(UTF-8)に日本
語タグ名があるファイルだと

 Message Unknown element 'プロジェクトコード'

とxercesに怒られます。
因みに同バージョンのwin32版だと正常に処理されます。
なぜなんでしょうか?
もしお分かりの方がいましたらお助け下さい。

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