0

ホストされたWebサイトにメッセージを記録するように設計している単純なクラスがあります。

メッセージを保存するために、次の単純なクラス構造を作成しました。

public class StoredMsg {
  public StoredMsg() {
  }
  public string From { get; set; }
  public string Date { get; set; }
  public string Message { get; set; }
}

これらのメッセージは、StoredMessages : List<StoredMsg>クラスを使用して書き込まれ、読み戻されます。

これは、Readメソッドの元の形式です。

  public void Read() {
    //string xmlPath = WebPage.Server.MapPath(XML_PATH);
    if (File.Exists(xmlPath)) {
      using (var xr = new XmlTextReader(xmlPath)) {
        StoredMsg item = null;
        while (xr.Read()) {
          if (xr.NodeType == XmlNodeType.Element) {
            if (xr.Name == HEAD) {
              if (item != null) {
                this.Add(item);
              }
              item = new StoredMsg();
            } else if (xr.Name == FROM) {
              item.From = xr.ReadElementString();
            } else if (xr.Name == DATE) {
              item.Date = xr.ReadElementString();
            } else if (xr.Name == MESSAGE) {
              item.Message = xr.ReadElementString();
            }
          }
        }
        xr.Close();
      }
    }
  }

このWriteメソッドは、もともと次の形式でした。

  public void Write(StoredMsg item) {
    using (var stream = File.Open(xmlPath, FileMode.Append, FileAccess.Write, FileShare.Read)) {
      using (var xw = new System.Xml.XmlTextWriter(stream, Encoding.UTF8)) {
        xw.WriteStartElement(HEAD);
        {
          xw.WriteWhitespace("\r\n\t");
          xw.WriteElementString(FROM, item.From);
          xw.WriteWhitespace("\r\n\t");
          xw.WriteElementString(DATE, item.Date);
          xw.WriteWhitespace("\r\n\t");
          xw.WriteElementString(MESSAGE, item.Message);
          xw.WriteWhitespace("\r\n");
        }
        xw.WriteEndElement();
        xw.WriteWhitespace("\r\n");
      }
      stream.Close();
    }
  }

問題は、このReadメソッドが XML の構造の一部を気に入らなかったため、リストが常に空だったことです。

ホストされた Web サイトでこれをトラブルシューティングするのは難しいため、オンラインで例を調べて、何が間違っているのかを調べ始めました。

検索中に、Microsoft の How to: Write Object Data to an XML File (C# and Visual Basic)Writeを見つけました。これは、私のメソッドが行ったことを簡素化する簡単な方法を示しています。

private XmlSerializer serializer;

public StoredMessages() {
  serializer = new XmlSerializer(typeof(StoredMsg));
}

public void Write(StoredMsg item) {
  using (var file = new StreamWriter(xmlPath, true)) {
    serializer.Serialize(file, item);
  }
}

それは、私にとって、シンプルさとエレガンスです!

これに満足したので、Microsoft の How to: Read Object Data from an XML File (C# and Visual Basic)に進み、それを実装することもできました。

問題は次のとおりです。

私ができる最善の方法は、次のようにメソッドを書くことです。

public void Read() {
  if (File.Exists(xmlPath)) {
    using (var file = new StreamReader(xmlPath)) {
      // How do I handle multiple nodes?
      // http://msdn.microsoft.com/en-us/library/vstudio/ms172872.aspx
      var item = (StoredMsg)serializer.Deserialize(file);
      this.Add(item);
    }
  }
}

Linq to XML ですべてのアイテムを読み取る方法を誰かが教えてくれるのを見ることに非常に興味があり、そのために +1 を付けますが、ここでの質問は、Read上記のこの手法を使用してすべてのデータを読み取る方法です。

逆シリアル化されたオブジェクトを他のものではなく誤ってキャストしているというStoredMsgことですか? もしそうなら、他の何かは何でしょうか?

  • StoredMsg[]?
  • List<object>?
  • StoredMessages?

これをすべて読んでくれてありがとう。私のコードが他の人にも読めることを願っています。

他のユーザーが私のメール アドレスを簡単に取得できないように、スクリーンショットとして提供されるデータの例:

スクリーンショット

4

2 に答える 2

1

同様の XML 構造を想定すると、次のようになります。

<Messages>
  <MessageHead>
    <From>Stackoverflow</From>
    <Date>09/05/2013</Date>
    <Message>Hello world</Message>
  </MessageHead>
  <MessageHead>
    <From>Stackoverflow</From>
    <Date>09/05/2013</Date>
    <Message>Second Message</Message>
  </MessageHead>
</Messages>

LINQ to XML クエリを使用して、各MessageHeadサブノードを 1 つのメッセージとして読み取ることができます。

var nodes = (from n in xml.Descendants("MessageHead")
             select new
             {
                 From = (string)n.Element("From").Value,
                 Date = (string)n.Element("Date").Value,
                 Message = (string)n.Element("Message").Value
             }).ToList();

これにより、以下を含む 2 つのノードのリストが得られます。

  • から
  • 日にち
  • メッセージ

そこから、それらをクラスにマップするのは非常に簡単です。

foreach (var n in nodes)
{
     StoredMessage s = new StoredMessage();
     s.from = n.From;
     s.date = n.Date;
     s.message = n.Message;
}
于 2013-05-09T14:25:16.623 に答える