C#使用内部具有变量名称的字符串设置变量

时间:2013-02-14 06:18:13

标签: c# xml system.reflection

*切换到serailization。

总结:我将所有变量预先定义为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

&GT;

是的我知道...... Feisar!现在只需使用turbosquid就可以了。

2 个答案:

答案 0 :(得分: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等从你需要的列表中选择一个。

答案 1 :(得分: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是类的名称,它将具有您要设置的所有属性