4

問題が発生しました。基本的にこれを逆シリアル化する必要があります。

<?xml version="1.0" encoding="UTF-8"?>
<api_data>
  <status>ok</status>
  <sessions>
    <id>2</id>
    <sessionID>6bfd1f1a7e87a8a6ed476234ad1d6e86</sessionID>
    <gameID>1</gameID>
    <maxPlayers>8</maxPlayers>
    <hostIP>12.0.0.1</hostIP>
    <hostPort>1993</hostPort>
    <inProgress>0</inProgress>
    <timestamp>1358894690</timestamp>
  </sessions>
  <sessions>
    <id>3</id>
    <sessionID>eeb4dc2df32f885c2b7d13f28a246830</sessionID>
    <gameID>1</gameID>
    <maxPlayers>8</maxPlayers>
    <hostIP>12.0.0.1</hostIP>
    <hostPort>1993</hostPort>
    <inProgress>0</inProgress>
    <timestamp>1358894732</timestamp>
  </sessions>
</api_data>

そして、それを使用可能なデータに変換する必要があります。これも動的であるため、2つ以上のセッション要素が存在する可能性があり、4、20、または0が存在する可能性があります。現在のコードは壊れているだけで、何が問題なのか疑問に思いました。これを機能させるための良い方法は?

現在、私はXDocumentクラスのポイントに到達しており、これらすべてがロードされています。そして、このデータを含む多次元配列を返す必要があります。

編集:

現在のコード、完全に壊れています:

var xmlSessions = xmlDATA.Descendants("api_data").Elements("sessions").Select(x => x);

result = new string[xmlDATA.Descendants("api_data").Count(), 7];

編集2:詳細

多次元配列を考えていたのは次のとおりです。

array[0,0] "ok" //Status
array[1,0 to 7] //First Session details go here
array[2,0 to 7] //Second session details go here, and so forth.
4

3 に答える 3

4

次のクラス表現を定義できます。

public class api_data
{
    public string status { get; set; }

    [XmlElement]
    public session[] sessions { get; set; }
}

public class session
{
    public int id { get; set; }
    public string sessionID { get; set; }
    public int gameID { get; set; }
    public int maxPlayers { get; set; }
    public string hostIP { get; set; }
    public int hostPort { get; set; }
    public int inProgress { get; set; }
    public int timestamp { get; set; }
}

キーはプロパティの[XmlElement]タグであり、提供したスキーマサンプルを使用してXMLの読み取り/書き込みをsessions指示します。それを逆シリアル化するには、次のようXmlSerializerに使用できます。XmlSerializer

//this might change, not sure how you obtain your xml, 
//but let's assume you already have it available as a string
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(xmlData); 

var stream = new MemoryStream(xmlBytes);
XmlSerializer serializer = new XmlSerializer(typeof(api_data));
api_data apidata = (api_data)serializer.Deserialize(stream);

それを読み込む(テストされて動作している)ために、それ以上のXML装飾やセットアップは必要ありません。

編集:他のXML属性を使用して、より優れた命名規則に移行することを検討することもできList<Session>ますが、配列の代わりに起動することもできます。

[XmlRoot("api_data")]
public class ApiData
{
    [XmlElement("status")]
    public string Status { get; set; }

    [XmlElement("sessions")]
    public List<Session> Sessions { get; set; }
}

public class Session
{
    [XmlElement("id")]
    public int ID { get; set; }

    [XmlElement("sessionID")]
    public string SessionID { get; set; }

    [XmlElement("gameID")]
    public int GameID { get; set; }

    [XmlElement("maxPlayers")]
    public int MaxPlayers { get; set; }

    [XmlElement("hostIP")]
    public string HostIP { get; set; }

    [XmlElement("hostPort")]
    public int HostPort { get; set; }

    [XmlElement("inProgress")]
    public int InProgress { get; set; }

    [XmlElement("timestamp")]
    public int TimeStamp { get; set; }
}

編集:これを多次元配列に変換する必要があることに気づきました(理由はわかりませんが、それはレガシーであると指定します)。この時点で、このデータ転送を実行できる優れたオブジェクトモデルができました。タイピングの方法はわかりませんが、object今のところ型配列を想定してみましょう。

ApiData apiData = DeserializeMyApiData(); // from above
array[0][0] = apiData.Status;
for(int i = 1; i <= apiData.Sessions.Count; i++)
{
    var session = apiData.Sessions[i - 1];
    array[i] = new object[8];
    array[i][0] = session.ID;
    array[i][1] = session.SessionID;
    array[i][2] = session.GameID;
    array[i][3] = session.MaxPlayers;
    array[i][4] = session.HostIP;
    array[i][5] = session.HostPort;
    array[i][6] = session.InProgress;
    array[i][7] = session.TimeStamp;
}

これにより、セッションの数に関係なく、アレイが構築されます。

于 2013-01-26T01:46:28.457 に答える
0

'sessions'タグを'session_list'タグ内にラップできますか?

もしそうなら、あなたはそれをロードするためにこのようなものを使うことができます:

public class api_data {

    public class sessions {
        public string id { get; set; }
        public string sessionID { get; set; }
        // put all the other vars in here ...
    }

    public string status { get; set; }           
    public List<sessions> session_list { get; set; }

    public static api_data LoadFromXML(string xmlFile) {

        api_data localApiData;

        // serialize from file
        try {
            var xs = new XmlSerializer(typeof(api_data),
                     new XmlRootAttribute("api_data"));
            using (TextReader tr = new StreamReader(xmlFile)) {
                localApiData= xs.Deserialize(tr) as api_data;
            }
        }
        catch (Exception ex) {
            Log.LogError(string.Format(
               "Error reading api_data file {0}: {1}",
               xmlFile, ex.Message));
            return null;
        }


        return localApiData;
    }
}

xmlファイルの形式を変更できない場合は、独自のステップでステータスをロードしてから、api-dataがリスト変数であるかのようにセッションをロードする必要があります。ただし、ステータスはそこにありますが、エラー。

于 2013-01-26T01:31:10.257 に答える
0

多次元配列のみが本当に必要な場合は、そのXMLから1行の(やや長い)コードでこれを取得できます。

string[][] items = XDocument.Parse(xml).Root.Elements().Select(e => e.HasElements ? e.Elements().Select(ei => ei.Value).ToArray() : new string[]{ e.Value }).ToArray();

または、同じ単一のステートメントをもう少し読みやすくするには、次のようにします。

string[][] items = 
    XDocument.Parse(xml).Root
             .Elements().Select(e => e.HasElements ? 
                 e.Elements().Select(ei => ei.Value).ToArray() : new string[]{ e.Value })
             .ToArray();

そのソースXMLから、次のような配列が生成されます。

string[][]
{
   { "ok" },
   { "2", "6bfd1f1a7e87a8a6ed476234ad1d6e86", "1", "8", "12.0.0.1", "1993", "0", "1358894690" },
   { "3", "eeb4dc2df32f885c2b7d13f28a246830", "1", "8", "12.0.0.1", "1993", "0", "1358894732" }
}

ステータスを個別に取得し、他の値を多次元配列に入れたい場合は、次のようにすることができます。

XDocument doc = XDocument.Parse(xml);
string status = doc.XPathSelectElement("/*/status").Value;
string[][] items = 
    doc.Root.Elements().Where(e => e.HasElements)
       .Select(e => e.Elements().Select(ei => ei.Value).ToArray()).ToArray();

これにより、ステータスが個々の文字列になり、アイテムに最初の単一要素配列が含まれないことを除いて、上記と同じように生成されます。

string[][]
{
   { "2", "6bfd1f1a7e87a8a6ed476234ad1d6e86", "1", "8", "12.0.0.1", "1993", "0", "1358894690" },
   { "3", "eeb4dc2df32f885c2b7d13f28a246830", "1", "8", "12.0.0.1", "1993", "0", "1358894732" }
}
于 2013-01-26T14:12:57.207 に答える