C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: 2つのList<>のシリアライズについて


(過去ログ 35 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■17389 / inTopicNo.1)  2つのList<>のシリアライズについて
  
□投稿者/ SAD (9回)-(2008/04/23(Wed) 12:25:17)

分類:[C++/CLI] 

2005 C++/CLI

2つのDictionaryを1つのXMLファイルに出力させたく、以下のようなものを作りました。
DicA、DicBには既に値がセットされているものとしてこれを実行すると、
//× 
という所で例外System.InvalidOperationExceptionが発生します。

「追加情報: 状態 EndRootElement のトークン StartElement は
XML ドキュメントを無効にする可能性があります。
XML フラグメントを書き込む場合は、ConformanceLevel の設定が
ConformanceLevel.Fragment または ConformanceLevel.Auto
になっていることを確認してください。 」

ということでしたので、
//        st->ConformanceLevel = System::Xml::ConformanceLevel::Auto;
を有効にして実行したところ、どうにかファイルに出力することはできました。

なぜ上記の1行を追加しなければならないのかがわかりません。
Autoにすると、宣言「<?xml version="1.0" encoding="utf-8"?>」が出力されなくなります。
AutoではなくDocumentとして出力させるにはどのようにすればよいのでしょうか?

public ref class Entry
{
public:
    Object^ Key;
    Object^ Value;
    Entry()
    {
    }
    Entry(Object^ key, Object^ value)
    {
        this->Key = key;
        this->Value = value;
    }
};

public ref class TestClass
{
public:
    Dictionary<int , String^>^ DicA;
    Dictionary<int , String^>^ DicB;

public:
    void Test()
    {
        XmlWriterSettings^ st = gcnew XmlWriterSettings();
        st->Encoding = System::Text::Encoding::UTF8;
        st->Indent = true;
//        st->ConformanceLevel = System::Xml::ConformanceLevel::Auto;

        XmlWriter^ xw = XmlWriter::Create(L"C:\\test.xml", st);
        XmlSerializer^ sr1 = gcnew XmlSerializer(List<Entry^>::typeid);

        List<Entry^>^ entries1 = gcnew List<Entry^>();

        xw->WriteStartElement("AAA");
        this->DicToEnt(entries1, this->DicA);	//DicAをentries1にコピー
        sr1->Serialize(xw, entries1);
        xw->WriteEndElement();

        xw->Flush();
        entries1->Clear();

        xw->WriteStartElement("BBB");			//×
        this->DicToEnt(entries1, this->DicB);	//DicBをentries1にコピー
        sr1->Serialize(xw, entries1);
        xw->WriteEndElement();

        xw->Close();
    }

引用返信 編集キー/
■17390 / inTopicNo.2)  Re[1]: 2つのList<>のシリアライズについて
□投稿者/ ネタ好き (141回)-(2008/04/23(Wed) 12:36:14)
No17389 (SAD さん) に返信
>st->ConformanceLevel = System::Xml::ConformanceLevel::Auto;
を有効にして実行したところ、どうにかファイルに出力することはできました。
なぜ上記の1行を追加しなければならないのかがわかりません。

>「追加情報: 状態 EndRootElement のトークン StartElement は
XML ドキュメントを無効にする可能性があります。
XML フラグメントを書き込む場合は、ConformanceLevel の設定が
ConformanceLevel.Fragment または ConformanceLevel.Auto
になっていることを確認してください。 」

これをよく読んでください。


引用返信 編集キー/
■17391 / inTopicNo.3)  Re[1]: 2つのList<>のシリアライズについて
□投稿者/ Hongliang (265回)-(2008/04/23(Wed) 12:41:19)
well-formed な XML は単一のルート要素を要求します。
XmlWriter はデフォルトでは ConformanceLevel は Document であり、well-formed な XML を要求します。
AAA 要素及び BBB 要素はどちらもルート要素となるため well-formed な XML になりません。
ConformanceLevel を Auto にした場合、二つ目のルート要素が書き込まれた時点で Fragment と判断するでしょう。
well-formed な XML にするために、適切な要素をルート要素にしてください。
// well-formed でない XML は「XML に似た何か」です。

また、一般的に XmlWriter を使用する場合は初めに WriteStartDocument、最後に WriteEndDocument を使用して XML 宣言を書き込みます。
引用返信 編集キー/
■17416 / inTopicNo.4)  Re[2]: 2つのList<>のシリアライズについて
□投稿者/ SAD (10回)-(2008/04/23(Wed) 17:25:21)
>ネタ好き様
そこを読んで、「なぜそのようなものが必要になるのか?」
と思い、質問した次第です。ヘルプでは、整形式に準拠するかどうかなど書いてありましたが、
http://msdn2.microsoft.com/ja-jp/library/h2344bs2.aspx
http://msdn2.microsoft.com/ja-jp/library/50f80zbz.aspx
調べているうちに、何か違う気がする、何か根本的に違っているとことがあるのでは?
と考えていました。(XmlWriterがどうとかではなく、それ以前の問題のような気がしていました。)
が、何をキーに探していけばよいのか掴めなかったもので・・。
(整形式(タグで囲まれた・・・)と、お前ルートねーじゃんよ・・というのが繋がりませんでした。)

>Hongliang様
そういうことですか。
言われて見ればルートタグがありませんね・・・。(AAA、BBBは、ルートにするつもりではありませんでしたので。)
well-formedは知っていたのですが・・・全く気づかず・・・。ちょっと悲しくなってきました。

xw->WriteStartDocument();
xw->WriteStartElement("XXX", "DDD");

xw->WriteEndElement();
xw->WriteEndDocument();

を追加したところ、動作しました。

お時間を割いて頂き、どうもありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -