- PR -

Xerces-C の使用法について2つの質問

1
投稿者投稿内容
Hiro
会議室デビュー日: 2002/05/30
投稿数: 7
投稿日時: 2002-05-30 13:58
ただいま、VC++6.0-SP5とXerces-C-1-5-2を使用してXMLパーサーを構築しています。
使用方法で解らない事が二つあり質問をします。

[1] SAXパーサーを利用してのDTDファイル名の取得。

SAXパーサーを利用して
任意に制定したのXMLドキュメントを解析していますが、
XMLファイルに指定しているDTDファイル名を取得するには
Xercesにて取得方法があるのでしょうか?
java だと取得方法があるのですけど・・・。

(例)

<!DOCTYPE TOPELEMENT SYSTEM "BaseSheet.dtd"> <--- "BaseSheet.dtd" を取得したい。

[2] DOMを使用してのXMLファイル出力時にXMLバージョンを出力させたい。

以下のような構築定義を行った後にDOMツリーを生成して、
XMLファイルに出力しているのですが
XML宣言文が出力されてなくて手法が間違っているのかなと思っております。。

(例)

--------------------------------------------

// ドキュメントインプリメンテーション。
DOM_DOMImplementation impl;
impl.hasFeature(DOMString("xml"), DOMString("1.0"));

// ドキュメントタイプを生成。
DOM_DocumentType doctype = impl.createDocumentType("TOPELEMENT", NULL, DOMString("BaseSheet.dtd"));
// ドキュメントルートを生成。
DOM_Document doc = impl.createDocument(
0, // root element namespace URI.
"TOPELEMENT", // root element name doctype); // document type object (DTD).

// DOMツリー生成する・・・

--------------------------------------------

<?xml version='1.0' encoding='Shift_JIS' ?> <--- この一文も出力したい。

ヘッダーファイルやサンプルを見ているのですが、
ピンと来るものがなくて質問しました。
よねくら
常連さん
会議室デビュー日: 2002/04/24
投稿数: 29
投稿日時: 2002-05-30 15:52
[1]
DefaultHandlerクラスに実装している

InputSource resolveEntity(String publicId, String systemId)

を使えばDTDのシステム識別子を取得できると思います。

[2]
XML宣言はDOMのノードに対応しないので、ファイルなどにXML文書を
出力する際に、強引に文字列として連結するしかないと思います。

ちなみに、MicrosoftのMSXMLは、XML宣言をPIノードとして扱って
います。
Hiro
会議室デビュー日: 2002/05/30
投稿数: 7
投稿日時: 2002-05-30 17:06
>>よねくらさん

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

[1]
>>DefaultHandlerクラスに実装している
>>InputSource resolveEntity(String publicId, String systemId)
>>を使えばDTDのシステム識別子を取得できると思います。

うー・・・私の質問が悪かったのでしょうか。
もしくはただ私が無知なだけなのか。
このメゾッドですと String publicId, String systemId は認知のものだと思います。
だとすると使用の際には String systemId にDTDファイル名をあてる事になるのだと思っています。
ところが・・・私はその String systemId に使用すると思われる
DTDファイル名を取得したいのです。
ちなみに、Xerces-C だと String ではなく XMLCh* ですね。

[2]
>>XML宣言はDOMのノードに対応しないので、ファイルなどにXML文書を
>>出力する際に、強引に文字列として連結するしかないと思います。

はい、やり方が解らないものでして
現在はその手法を採っていました
コードが汚いので綺麗なやり方があるかなと思い質問をする事にしたのです。
やはりその方法しかないでしょうか。
よねくら
常連さん
会議室デビュー日: 2002/04/24
投稿数: 29
投稿日時: 2002-05-30 19:52
resolveEntityはSAXパーサから呼ばれるイベントメソッドです。
なので(以下はJavaの記述ですが)、次のようにSystem IDを参照
できると思います。

class MyHandler extents DefaultHandler
{
public InputSource resolveEntity(String publicId, String systemId)
{
// SAXパーサにより通知されたpublicIdを参照する
}
}

Hiro
会議室デビュー日: 2002/05/30
投稿数: 7
投稿日時: 2002-05-31 13:25
>>よねくらさん

あれから調べてみましたが、
御指摘の resolveEntity は外部エンティティが定義されていた場合に呼び出される
イベントハンドラですよね?
ともすると、

<!DOCTYPE TOPELEMENT SYSTEM "BaseSheet.dtd">

DOCTYPE 定義とは違うわけであってハンドラを実装してもコールされないし、
実際にコールされなかったんですが・・・。
よねくら
常連さん
会議室デビュー日: 2002/04/24
投稿数: 29
投稿日時: 2002-05-31 18:40
以下を参照してみてください。

http://www.saxproject.org/apidoc/org/xml/sax/EntityResolver.html

ここに次のような記述があります。

The XML reader will then allow the application to intercept any external entities (including the external DTD subset and external parameter entities, if any) before including them.
よねくら
常連さん
会議室デビュー日: 2002/04/24
投稿数: 29
投稿日時: 2002-05-31 18:42
すみません。ひとつ忘れていました。
イベントメソッドを実装するだけではなく、
SAXパーサにsetEntityResolverメソッドをつかって
イベントハンドラを登録する必要があります。
Hiro
会議室デビュー日: 2002/05/30
投稿数: 7
投稿日時: 2002-06-03 10:05
>>よねくらさん

アドバイスどうもでした。
そのやり方で取得できました!
また何かありましたらよろしく願います!
1

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