2013-02-14 52 views
0

*切换到分离。C#使用内部具有变量名称的字符串设置变量

摘要:我将所有变量预先定义为null/0.我想使用来自和XML文档的数据来设置它们。该文档包含与变量完全相同的名称。我不想使用其他一些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文件中的变量与类中的变量具有完全相同的格式和名称。 Class中的maxSpeed是XML文件中的maxSpeed。

我的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!现在只需从turbosquid放置持有者即可。

+1

我不明白你的第三和第四步......?你是这些变量的一部分吗?而且,这个类是否可以直接从XML文档反序列化呢?最后:实际上并不确定你在问什么:) – baldric 2013-02-14 06:24:20

+0

你的类的示例是有用的(假设“变量”是指类的属性/字段,而不是某种方法的局部变量)。 – 2013-02-14 06:25:49

+0

从我正在做的事情更新代码。我试图设置变量而不用说speed = attribute.innertext。 我想说[Psuedo] attribute.name.thisIsNowTheVariable =属性。的innerText; 属性是一个XML节点。 – 2013-02-14 06:32:36

回答

3

创建一个类来保存您正在阅读的值并使用XML序列化。

Microsoft Tutorial

Tech Pro Tutorial

MSDN: XmlSerializer

编辑:

如果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); 
} 

编辑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

我没遇到过这个,还没有尝试过序列化呢。这对我来说是新的。如果另一种方式行不通,明天就会解决。 – 2013-02-14 06:45:16

+0

编辑: 有趣的,所以如果我把变量的顺序放在类里面的顺序是相同的,那么这会设置类中的所有属性,因为它被读入? – 2013-02-14 21:01:31

+0

Errr,唯一的问题是,我将在XML中存储多艘船,所以我必须能够跳过它们,直到找到我需要的船。反序列化似乎不允许这种类型的工作。 – 2013-02-14 21:15:03

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 2013-02-14 06:38:51

+0

我会给这个看看当我的大脑没有入睡。我明天会就此回复你。 – 2013-02-14 06:44:35