2013-02-14 2 views
0

* Переключилось на serailization.C# Задайте переменную, используя строку с переменным именем внутри

Реферат: У меня есть все переменные, предварительно определенные как null/0. Я хочу установить их с помощью данных и XML-документа. Документ содержит те же имена, что и переменные. Я не хочу использовать кучу else ifs, поэтому я пытаюсь сделать это на основе имен, которые я извлекаю из документа XML.

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 
using System.Reflection; 
using System.Text; 
using System.Xml; 
using System.IO; 

public class ShipAttributes 
{ 
    // Model Information 
    string name; 
    string modelName; 
    string firingPosition; 
    string cameraPosition; 
    string cargoPosition; 
    Vector3 cameraDistance; 

    // Rotation 
    float yawSpeed; 
    float pitchSpeed; 
    float rollSpeed; 

    // Speed 
    float maxSpeed; 
    float cruiseSpeed; 
    float drag; 
    float maxAcceleration; 
    float maxDeceleration; 

    // Physics Properties 
    float mass; 

    // Collection Capacity 
    float cargoSpace; 

    // Combat [Defense] 
    float structureHealth; 
    float armorHealth; 
    float shieldHealth; 
    float shieldRadius; 

    // Combat [Assault] 
    float missileRechargeTime; 
    float fireRate; 

    // Currency Related 
    float cost; 
    float repairMultiplier; 

void PopulateShipList() 
{ 
    if (shipList != null) 
     return; 

    string filepath = Application.dataPath + "/Resources/shipsdata.xml"; 

    XmlRootAttribute xml_Root = new XmlRootAttribute(); 
    xml_Root.ElementName = "SHIPS"; 
    xml_Root.IsNullable = true; 
    //using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) 
    //{ 
     StringReader stringReader = new StringReader(filepath); 
     stringReader.Read(); 
     XmlReader xRdr = XmlReader.Create(stringReader); 
     XmlSerializer xml_s = new XmlSerializer(typeof(List<ShipAttributes>), xml_Root); 
     shipList= (List<ShipAttributes>)xml_s.Deserialize(xRdr); 
    //} 
} 
public ShipAttributes LoadShip(string inName) 
{ 
    PopulateShipList(); 
    foreach (ShipAttributes att in shipList) 
    { 
     if (att.name == inName) 
     { 
      att.shipList = shipList; 
      return att; 
     } 
    } 

    return null; 
} 

* Примечание. Переменные в файлах XML имеют тот же формат и имя, что и переменные в классе. maxSpeed ​​в классе maxSpeed ​​в XML-файле.

Мой XML выглядит следующим образом -

<?xml version="1.0" encoding="UTF-8 without BOM" ?> 

    <SHIPS> 
     <SHIP> 
      <name>Default</name> 
      <id>0</id> 
      <modelName>Feisar_Ship</modelName> 
      <firingPosition>null</firingPosition> 
      <cameraPosition>null</cameraPosition> 
      <cargoPosition>null</cargoPosition> 
      <cameraDistance>null</cameraDistance> 
      <yawSpeed>2000.0</yawSpeed> 
      <pitchSpeed>3000.0</pitchSpeed> 
      <rollSpeed>10000.15</rollSpeed> 
      <maxSpeed>200000.0</maxSpeed> 
      <cruiseSpeed>100000.0</cruiseSpeed> 
      <drag>0.0</drag> 
      <maxAcceleration>null</maxAcceleration> 
      <maxDeceleration>null</maxDeceleration> 
      <mass>5000.0</mass> 
      <cargoSpace>150.0</cargoSpace> 
      <structureHealth>100.0</structureHealth> 
      <armorHealth>25.0</armorHealth> 
      <shieldHealth>25.0</shieldHealth> 
      <shieldRadius>30.0</shieldRadius> 
      <missileRechargeTime>2.0</missileRechargeTime> 
      <fireRate>0.5f</fireRate> 
      <cost>0</cost> 
      <repairMultiplier>1.0</repairMultiplier> 
     </SHIP> 
    </SHIPS 

>

Да я знаю ... Feisar! Просто разместите держатели сейчас от турбоакустических.

+1

Я не понимаю ваши 3-й и 4-й шаги ...? Являются ли эти переменные вашей частью класса? И может ли этот класс просто десериализоваться из XML-документа напрямую? Наконец: на самом деле не уверен, что вы просите :) – baldric

+0

Пример вашего класса был бы полезен (предполагая, что «переменная» означает свойство/поле класса, а не локальную переменную какого-либо метода). –

+0

Обновлен с кодом от того, что я делаю. Я пытаюсь установить переменные, не сказав speed = attribute.innertext. Я хочу сказать [Psuedo] attribute.name.thisIsNowTheVariable = attribute.InnerText; Атрибут является узлом XML. –

ответ

3

Создайте класс для хранения значений, которые вы читаете, и используйте XML-сериализацию.

Microsoft Tutorial

Tech Pro Tutorial

MSDN: XmlSerializer

EDIT:

Если XML точно так же, как класс кода, публикуемую, следующее должно позволить вам получить класс от ShipAttributes:

ShipAttributes attributes = null; 
string filepath = "/path/to/xml"; 

using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { 
    var xml_s = new XmlSerializer(typeof(ShipAttributes)); 

    attributes = (ShipAttributes)xml_s.Deserialize(stream); 
} 

Edit 2: Множественное судно

В своем комментарии, вы сказали, что файл содержит несколько ShipAttribute описаний. Способ справиться с этим так же, как и выше, но десериализация файла в тип List<ShipAttribute> следующим образом:

List<ShipAttributes> ships = null; 
string filepath = "/path/to/xml"; 

using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { 
    var xml_s = new XmlSerializer(typeof(List<ShipAttributes>)); 

    ships= (List<ShipAttributes>)xml_s.Deserialize(stream); 
} 

После того, как вы сделали это, у вас есть все корабли в памяти и можете выбрать один из из списка нужно с помощью Linq и т.д.

+0

Я столкнулся с этим, еще не пробовал сериализацию. Это будет для меня ново. Завтра будет работать, если другой способ не работает. –

+0

Редактировать: Интересно, поэтому, если я поместил порядок переменных в XML в том же порядке, в котором они находятся внутри класса, это установило бы все атрибуты в классе по мере его чтения? –

+0

Errr, Единственная проблема с этим, я буду хранить несколько кораблей в XML, поэтому я должен быть в состоянии пропустить их, пока не найду, какое судно мне нужно. Кажется, что десериализация не разрешает этот вид работы. –

0

Предполагая, что вы XML-файл

<?xml version="1.0" encoding="utf-8"?> 
<Variables>  
    <VariableName1>1</VariableName1> 
    <VariableName2>test</VariableName2> 
    <VariableName3>test2</VariableName3>  
</Variables> 



var data = XDocument.Load("YourXML.xml"); 
var xmldata = from x in data.Descendants("Variables")       
         select x; 

notes.Select(_BuildPropertyFromElement); 



private Yourclassname _BuildNoteFromElement(XElement element) 
    { 
     var type = typeof(**Yourclassname**); 
     var Details = new Yourclassname(); 

     foreach (var propInfo in type.GetProperties()) 
     { 
     var rawValue = element.Element(propInfo.Name).Value; 
     var convertedValue = propInfo.PropertyType == typeof(DateTime) ?   (object)Convert.ToDateTime(rawValue) : rawValue; 
      propInfo.SetValue(Details , convertedValue, null); 
       } 

       return Details ; 
      } 

YOURCLASSNAME это имя класса, который будет иметь все свойства, которые вы хотите, чтобы как таковые t до

+0

Правильный путь будет сериализовать его, но я опубликовал его так, как вы пытаетесь – Chief

+0

. Я дам это посмотреть, когда мой мозг не засыпает. Я вернусь к вам завтра. –

Смежные вопросы