Ich habe Schwierigkeiten, diese scheinbar einfache Aufgabe zu erledigen. Ich möchte XML-Dateien mit der gleichen Leichtigkeit des Ladens von Art Assets laden:XNA: Der beste Weg, um eine XML-Datei zu laden und zu lesen?
content = new ContentManager(Services);
content.RootDirectory = "Content";
Texture2d background = content.Load<Texture2D>("images\\ice");
Ich bin mir nicht sicher, wie dies zu tun ist. Diese tutorial scheint hilfreich, aber wie bekomme ich eine StorageDevice
Instanz?
ich habe jetzt etwas zu arbeiten, aber es fühlt sich ziemlich hacky:
public IDictionary<string, string> Get(string typeName)
{
IDictionary<String, String> result = new Dictionary<String, String>();
xmlReader.Read(); // get past the XML declaration
string element = null;
string text = null;
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element:
element = xmlReader.Name;
break;
case XmlNodeType.Text:
text = xmlReader.Value;
break;
}
if (text != null && element != null)
{
result[element] = text;
text = null;
element = null;
}
}
return result;
}
ich diese Datei in der folgenden XML-Anwendung:
<?xml version="1.0" encoding="utf-8" ?>
<zombies>
<zombie>
<health>100</health>
<positionX>23</positionX>
<positionY>12</positionY>
<speed>2</speed>
</zombie>
</zombies>
Und es ist in der Lage diese Einheit Test bestehen:
Nachteile der aktuellen Ansatz: Datei laden ist schlecht gemacht, und übereinstimmende Schlüssel zu Werten scheint es ist viel mehr Aufwand als nötig. Außerdem vermute ich, dass dieser Ansatz mit mehr als einem Eintrag in der XML auseinander fallen würde.
Ich kann mir nicht vorstellen, dass dies die optimale Implementierung ist.
UPDATE: Im Anschluss an die Beratung von @ Peter Lillevold, habe ich dies ein wenig geändert:
public IDictionary<string, string> Get(string typeName)
{
IDictionary<String, String> result = new Dictionary<String, String>();
IEnumerable<XElement> zombieValues = root.Element(@typeName).Elements();
//result["health"] = zombie.Element("health").ToString();
IDictionary<string, XElement> nameToElement = zombieValues.ToDictionary(element => element.Name.ToString());
foreach (KeyValuePair<string, XElement> entry in nameToElement)
{
result[entry.Key] = entry.Value.FirstNode.ToString();
}
return result;
}
public ReadWriteXML(string uri)
{
root = XElement.Load(uri);
}
internal virtual IPersistentState CreateIPersistentState(string fullpath)
{
return new ReadWriteXML(fullpath);
}
/// <summary>
///A test for Get with one zombie.
///</summary>
[TestMethod()]
public void SimpleGetTest()
{
IPersistentState target = CreateIPersistentState("../../../path/Data/SavedZombies.xml");
string typeName = "zombie";
IDictionary<string, string> expected = new Dictionary<string, string>();
expected["health"] = "100";
expected["positionX"] = "23";
expected["positionY"] = "12";
expected["speed"] = "2";
IDictionary<string, string> actual = target.Get(typeName);
foreach (KeyValuePair<string, string> entry in expected)
{
Assert.AreEqual(entry.Value, actual[entry.Key]);
}
}
Der Laden ist immer noch ziemlich beschissen ist, und irgendwie war ich nicht in der Lage, die ein- bis bekommen Linie ToDictionary
mit diesen beiden Lambdas arbeiten. Ich musste auf diese foreach-Schleife zurückgreifen. Was mache ich da falsch?
Sie haben einen Tippfehler dort. Das @ aus meinem Beispiel kann nur mit String-Literalen, nicht mit String-Variablen oder Parametern verwendet werden. –
Sie erkennen, dass die XNA-Content-Pipeline unterstützt XML-Dateien, nein? Sie können also die gleiche Syntax verwenden, die Sie zum Laden von XML-Dateien verwenden. –