14

.xml で構成の一部を表すクラス ライブラリを使用しています。構成は、 を使用して読み込まれますXmlSerializer。幸いなことに、.xml を表すクラスはXmlAnyElement、元のクラス ライブラリを変更せずに独自の目的のために構成データを拡張できる at 属性を使用します。

<?xml version="1.0" encoding="utf-8"?>
<Config>
  <data>This is some data</data>
  <MyConfig>
    <data>This is my data</data>
  </MyConfig>
</Config>

これは、逆シリアル化に適しています。クラス ライブラリが.xmlを通常どおり逆シリアル化できるようにすることができXmlSerializerます。XmlNodeReaderXmlNode

public class Config
{
    [XmlElement]
    public string data;

    [XmlAnyElement]
    public XmlNode element;
}

public class MyConfig
{
    [XmlElement] 
    public string data;
}

class Program
{
    static void Main(string[] args)
    {
        using (Stream fs = new FileStream(@"c:\temp\xmltest.xml", FileMode.Open))
        {
            XmlSerializer xser1 = new XmlSerializer(typeof(Config));
            Config config = (Config)xser1.Deserialize(fs);

            if (config.element != null)
            {
                XmlSerializer xser2 = new XmlSerializer(typeof(MyConfig));
                MyConfig myConfig = (MyConfig)xser2.Deserialize(new XmlNodeReader(config.element));
            }
        }
    }

ユーザーがクラス ライブラリ構成と独自の構成の両方を含む新しい構成ファイルを生成できるようにするユーティリティを作成する必要があるため、.xml ファイルから読み取られなかった新しいオブジェクトが作成されます。問題は、データをシリアル化して .xml に戻すにはどうすればよいかということです。

XmlSerializer.Serializeクラス ライブラリ構成で同じメソッドを呼び出す前に、最初に自分のデータを呼び出す必要があることに気付きました。XmlNodeただし、これには私のデータがafter 呼び出しで表される必要がありSerializeます。XmlNodeを使用してオブジェクトをシリアル化する最良の方法は何XmlSerializerですか?

ありがとう、

-ケビン

ところでXmlNodeWriter-- Chris Lovett によって書かれたクラスが Microsoft から一度に入手可能だったようですが、リンクは現在壊れています。このクラスを取得する別の場所を知っている人はいますか?

4

4 に答える 4

13

したがって、クラスにカスタム構成情報を含める必要があります。次に、そのクラスをXMLにシリアル化し、そのシリアル化されたXMLをXMLノードにします。そうですか?

XMLSerializerによって作成された文字列を取得し、それを独自のXMLタグでラップできますか?

XmlSerializer xs = new XmlSerializer(typeof(MyConfig));
StringWriter xout = new StringWriter();
xs.Serialize(xout, myConfig);
XmlDocument x = new XmlDocument();
x.LoadXml("<myConfig>" + xout.ToString() + "</myConfig>");

これで、xは、シリアル化されたカスタム構成を含む1つの要素「<myconfig>」を含むXmlDocumentになります。

それはあなたが探しているものですか?

于 2008-09-05T17:43:28.387 に答える
3

少し手間がかかりましたが、XPathNavigator ルートは機能します... XmlWriter で .Close を呼び出すことを忘れないでください。.Flush() は何もしません。

//DataContractSerializer serializer = new DataContractSerializer(typeof(foo));
XmlSerializer serializer = new XmlSerializer(typeof(foo));

XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
XmlWriter writer = nav.AppendChild();
writer.WriteStartDocument();
//serializer.WriteObject(writer, new foo { bar = 42 });
serializer.Serialize(writer, new foo { bar = 42 });
writer.WriteEndDocument();
writer.Flush();
writer.Close();

Console.WriteLine(doc.OuterXml);
于 2008-11-21T03:11:44.923 に答える
0

1 つの解決策は、内側のオブジェクトを文字列にシリアル化し、その文字列を XmlDocument に読み込んで、データを表す XmlNode を見つけ、それを外側のオブジェクトに添付することです。

XmlSerializer xser1 = new XmlSerializer(typeof(Config));
XmlSerializer xser2 = new XmlSerializer(typeof(MyConfig));

MyConfig myConfig = new MyConfig();
myConfig.data = "My special data";

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlWriter xw = new XmlTextWriter(sw);
xser2.Serialize(xw, myConfig);

XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());

Config config = new Config();
config.data = "some new info";
config.element = doc.LastChild;

xser1.Serialize(fs, config);

ただし、この解決策は面倒であり、より良い方法があることを願っていますが、今のところ問題は解決しています。

いくつかのブログで言及されている神話上の XmlNodeWriter を見つけることができれば!

于 2008-09-05T17:52:10.550 に答える
0

XmlNodeWriter の代替として、少なくとも 1 つのリソースがこれを指しています: http://msdn.microsoft.com/en-us/library/5x8bxy86.aspx。それ以外の場合は、XmlNodeWriter を検索する GotDotNet の新しい MSDN コード ライブラリの代替にあるフォームを使用して、MS を作成できます。

于 2008-09-05T18:15:02.570 に答える