3

次の Xml 構造をシリアル化したい:

  <XmlRootElement>
     <Company name="Acme Widgets LLC">
        <DbApplication name="ApplicationA" vendor="oracle">
           <ConnSpec environment="DEV" 
                     server="DBOraDev1201" 
                     database="AppA" 
                     userId="MyUser" 
                     password="5613456#6%^%$%$#" />
           <ConnSpec environment="QA" 
                     server="DBOraQA1205" 
                     database="AppA" 
                     userId="MyUser" 
                     password="5613456#6%^%$%$#" />
       </DbApplication>
       <DbApplication name="AnotherApp" "vendor="SQLServer">
           <ConnSpec environment="DEV" 
                     server="DBMsSqlDev1201" 
                     catalog="AnoptherApp" 
                     userId="MyUser" 
                     password="5613456#6%^%$%$#" />
           <ConnSpec environment="QA" 
                     server="DBMsSqlQA1565" 
                     catalog="AnotherApp" 
                     userId="MyUser" 
                     password="5613456#6%^%$%$#" />
       </DbApplication>
     </Company>
     <Company name = "ExpertSoftware Inc" ....
        ...
     </Company>
  </XmlRootElement>

しかし、私はリンクテキストで発見しました

上記のリンクからの引用: ...

  • Q: コレクション クラスのすべてのプロパティがシリアル化されないのはなぜですか?
  • A: XmlSerializer は、IEnumerable または ICollection インターフェイスを検出した場合にのみ、コレクション内の要素をシリアル化します。この動作は仕様です。唯一の回避策は、カスタム コレクションを 2 つのクラスにリファクタリングすることです。そのうちの 1 つは、純粋なコレクション型の 1 つを含むプロパティを公開します。

...

他の Xml 属性を持つコレクションをシリアル化または逆シリアル化できないことを発見した後...推奨される回避策は、コレクションを持つ要素を他の属性を持つ要素から分離することです...つまり、代わりに次のように構造を変更します。

  <XmlRootElement>
     <Companys>
        <Company name="Acme Widgets LLC">
           <DbApplications>
               <DbApplication name="ApplicationA" vendor="oracle">
                  <ConnSpecs>
                     <ConnSpec environment="DEV" 
                         server="DBOraDev1201" ...  />
                     <ConnSpec environment="QA" 
                         server="DBOraQA1205" 
                         database="AppA" ... />
                  </ConnSpecs>
               </DbApplication>
               <DbApplication name="AnotherApp" "vendor="SQLServer">
                  <ConnSpecs>
                      <ConnSpec environment="DEV" ... />
                      <ConnSpec environment="QA"  ... />
                  </ConnSpecs>
                </DbApplication>
           </DbApplications>
         </Company>
         <Company name = "ExpertSoftware Inc" ....
             ...
         </Company>
     </Companys>
  </XmlRootElement>

なぜそうなのか誰か知っていますか?または、これを行う他の方法がある場合は?

4

2 に答える 2

2

XmlSerializerを使用している場合は、コレクションをシリアル化する方法を示す必要があります。

public class XmlRootElement
{
    [XmlElement(ElementName="Company")]
    public Company[] Company { get; set; }

    // Other properties ....
}

public class Company
{
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }

    [XmlElement(ElementName = "DbApplication")]
    public DbApplication[] DbApplication { get; set; }

    // Other properties ....
}

public class DbApplication
{
    [XmlElement(ElementName = "ConnSpec")]
    public ConnSpec[] ConnSpec { get; set; }

    // Other properties ....
}

public class ConnSpec
{
    // Other properties ....
}

その後:

using (Stream stream = new FileStream("test.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    XmlSerializer serializer = new XmlSerializer(typeof(XmlRootElement));
    XmlRootElement root = (XmlRootElement)serializer.Deserialize(stream);
}

お役に立てれば。

于 2008-11-30T11:53:47.303 に答える
1

XMl シリアル化属性をすべてのクラスに追加する代わりに、ルート要素コンテナー クラスにIXmlSerializableインターフェイスを実装することもできます。このインターフェイスのReadXmlおよびWriteXmlメソッドは XmlSerializer によって使用され、シリアル化/逆シリアル化プロセスをより細かく制御できます。

于 2008-12-01T16:31:51.033 に答える