2017-03-29 20 views
0

xmlからオブジェクトを逆シリアル化していますが、KeywordListとResponseListの文字列は常に空になります。Xml欠落している文字列を逆シリアル化する

多くのことを試してみると、それは正しいとは言えません。私がそれを読者でループすると、値が表示されます。ここで

using System; 
using System.Collections.Specialized; 
using System.Xml; 
using System.Xml.Serialization; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(ElizaResponses)); 
      using (XmlReader reader = XmlReader.Create("eliza.xml")) 
      { 
       ElizaResponses responses = (ElizaResponses)serializer.Deserialize(reader); 
       reader.Close(); 

       // This reads in all data 
       //StreamReader reader = new StreamReader("eliza.xml"); 
       //reader.ReadToEnd(); 
       //reader.MoveToContent(); 
       //while (reader.Read()) 
       //{ 
       // if(reader.NodeType == XmlNodeType.Text) 
       // { 
       //  Console.WriteLine("{0}, {1}", reader.NodeType, reader.Value); 
       // } 
       // else 
       // { 
       // Console.WriteLine("{0}, {1}", reader.NodeType, reader.Name); 
       // } 
       //} 


      } 

      Console.ReadLine(); 
     } 
    } 

    [Serializable] 
    [XmlRoot("ElizaResponses")] 
    [XmlType("ElizaResponses")] 
    public sealed class ElizaResponses 
    { 
     ElizaConversation[] chatList; 

     public ElizaConversation[] ChatList 
     { 
      get { return this.chatList; } 
      set { this.chatList = value; } 
     } 
    } 

    [Serializable] 
    public sealed class ElizaConversation 
    { 
     // Tried List<string>, string[], StringCollection 
     StringCollection keywordList = new StringCollection(); 
     StringCollection responseList = new StringCollection(); 

     // Tried [XmlArray], [XmlElement] 
     [XmlElement("KeywordList")] 
     [XmlArrayItem("string", typeof(string))] 
     StringCollection KeywordList 
     { 
      get { return this.keywordList; } 
      set { this.keywordList = value; } 
     } 

     [XmlArray("ResponseList")] 
     [XmlArrayItem("string", typeof(string))] 
     StringCollection ResponseList 
     { 
      get { return this.responseList; } 
      set { this.responseList = value; } 
     } 
    } 
} 

は、私は例外を取得していないし、答えを見つけapp.configファイル

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> 
    </startup> 
    <system.diagnostics> 
    <switches> 
     <add name="XmlSerialization.Compilation" value="4" /> 
    </switches> 
    </system.diagnostics> 
</configuration> 

答えて

0

にエラーメッセージが上がっている追加する必要があります例のXML

<?xml version="1.0" encoding="utf-8"?> 
<ElizaResponses> 
    <ChatList> 
    <ElizaConversation> 
     <KeywordList> 
     <string>ok</string> 
     </KeywordList> 
     <ResponseList> 
     <string>cool.</string> 
     <string>great.</string> 
     <string>:)</string> 
     </ResponseList> 
    </ElizaConversation> 
    <ElizaConversation> 
     <KeywordList> 
     <string>shutup</string> 
     <string>shut up</string> 
     </KeywordList> 
     <ResponseList> 
     <string>make me.</string> 
     <string>no I won't.</string> 
     </ResponseList> 
    </ElizaConversation> 
    </ChatList> 
</ElizaResponses> 

です。プロパティはパブリックではないため、設定できません。

1

タイプを手動で生成しようとするよりも、自動的に生成し、自動生成されたタイプの動作を確認することから始めてください。それだけで、必要に応じて簡素化します。あなたがhttp://xmltocsharp.azurewebsites.net/にあなたのXMLを投稿する場合、あなたはXMLをデシリアライズしますクラスを生成することができます

[XmlRoot(ElementName = "KeywordList")] 
public class KeywordList 
{ 
    [XmlElement(ElementName = "string")] 
    public List<string> String { get; set; } 
} 

[XmlRoot(ElementName = "ResponseList")] 
public class ResponseList 
{ 
    [XmlElement(ElementName = "string")] 
    public List<string> String { get; set; } 
} 

[XmlRoot(ElementName = "ElizaConversation")] 
public class ElizaConversation 
{ 
    [XmlElement(ElementName = "KeywordList")] 
    public KeywordList KeywordList { get; set; } 
    [XmlElement(ElementName = "ResponseList")] 
    public ResponseList ResponseList { get; set; } 
} 

[XmlRoot(ElementName = "ChatList")] 
public class ChatList 
{ 
    [XmlElement(ElementName = "ElizaConversation")] 
    public List<ElizaConversation> ElizaConversation { get; set; } 
} 

[XmlRoot(ElementName = "ElizaResponses")] 
public class ElizaResponses 
{ 
    [XmlElement(ElementName = "ChatList")] 
    public ChatList ChatList { get; set; } 
} 

をあなたはその上ElizaResponsesのこのバージョンをお使いのコードを使用して確認することができ、あなたのXMLをデシリアライズします。しかしながら、これらは単純化することができる。

まず、StringListKeywordListResponseListをマージ:

public class StringList 
{ 
    [XmlElement(ElementName = "string")] 
    public List<string> String { get; set; } 
} 

[XmlRoot(ElementName = "ElizaConversation")] 
public class ElizaConversation 
{ 
    [XmlElement(ElementName = "KeywordList")] 
    public StringList KeywordList { get; set; } 
    [XmlElement(ElementName = "ResponseList")] 
    public StringList ResponseList { get; set; } 
} 

次に、StringListは完全List<string<>に置き換えるなくします。コンテナクラスの追加レベルが解消されているので、2つの[XmlElement]属性が[XmlArray][XmlArrayItem]は、以下の最終バージョンになると置き換える必要があります:

    :あなたの最初の試みは、次のような問題が含まれ
    [XmlRoot(ElementName = "ElizaConversation")] 
    public class ElizaConversation 
    { 
        [XmlArray(ElementName = "KeywordList")] 
        [XmlArrayItem(ElementName = "string")] 
        public List<string> KeywordList { get; set; } 
        [XmlArray(ElementName = "ResponseList")] 
        [XmlArrayItem(ElementName = "string")] 
        public List<string> ResponseList { get; set; } 
    } 
    
    [XmlRoot(ElementName = "ChatList")] 
    public class ChatList 
    { 
        [XmlElement(ElementName = "ElizaConversation")] 
        public List<ElizaConversation> ElizaConversation { get; set; } 
    } 
    
    [XmlRoot(ElementName = "ElizaResponses")] 
    public class ElizaResponses 
    { 
        [XmlElement(ElementName = "ChatList")] 
        public ChatList ChatList { get; set; } 
    } 
    

  • 非一般的な、廃止されたStringCollectionは避けるべきです。
  • [XmlArrayItem("Item", typeof(string))]宣言では、"Item"という名前は間違っています。それは"string"だったはずです。
  • [XmlElement][XmlArrayItem]を組み合わせることはできません。
  • プロパティKeywordListResponseListは公開されていません。 XmlSerializerは、パブリックメンバーのみをシリアル化します。

サンプルfiddle

関連する問題