我的应用程序有一个配置xml文件。该文件包含50多个程序设置。目前,我分别阅读并保存每个程序设置。我猜这样的任务没有效率。
我需要能够自动生成加载代码的东西,并使用预定义的xml-schema保存我的程序设置。
我在添加新项对话框中找到了一个数据集。不幸的是,由于这个
,我无法向dataset1添加新代码,例如属性的set-accessors中的事件// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
也许,有一个工具允许用户生成一个用于访问xml文件的包装器?例如DataSet1,但具有添加事件的可用性。
编辑:我没有标记有用的答案,因为我读了你给我的文章(链接)。我稍后会标出有用的答案。
答案 0 :(得分:2)
如果您的xml文件有适当的xsd架构,则microsoft提供 xsd.exe ,这是一个为此架构自动生成c#类的小工具。
有关详细信息,请参阅:http://msdn.microsoft.com/en-us/library/x6c1kb0s%28VS.71%29.aspx
答案 1 :(得分:2)
如果你不愿意使用app.config / web.config或属性文件(Oded和Bruno推荐我也推荐),我强烈推荐这个实用程序:
VS2008和VS2010Web Services Contract First (WSCF) Blue
如果您使用的是VS2005,则需要使用此版本的工具:http://www.thinktecture.com/resourcearchive/tools-and-software/wscf(请勿在此网站上使用VS2008版本。我永远无法使其正常工作。)
将插件安装到Visual Studio后,您将需要XML文件的XSD架构。 (Google for an online XSD Generator。)按照WSCF网站上的说明,您可以生成一个包装类,它将对XML进行反序列化和重新序列化,并为您提供XML的抽象视图。
我认为添加新节点/元素TYPES是不可能的(或者至少很难),但是添加现有节点/元素类型的新实例,访问数据,编辑数据,重新排序节点,然后保存回来出去都很容易。
反序列化代码如下所示:
private MyGeneratedXMLconfigClass config;
using (StreamReader sr = new StreamReader(filename))
{
XmlSerializer cXml = new XmlSerializer(typeof(MyGeneratedXMLconfigClass));
config = (MyGeneratedXMLconfigClass)cXml.Deserialize(sr);
}
现在您的XML已反序列化到自定义类的“config”实例中。然后,您可以将整个类作为一系列嵌套值和列表访问。
例如:
string errorFile = config.errorsFile;
List<string> actions = config.actionList;
var specialActions = from action in config.actionList
where action.contains("special")
select action;
等等。然后,一旦完成操作数据,就可以使用以下代码重新序列化:
using (StreamWriter wr = new StreamWriter(filename, false))
{
XmlSerializer cXml = new XmlSerializer(typeof(MyGeneratedXMLconfigClass));
cXml.Serialize(wr, config);
}
这个工具的一个非常好的事情是它自动生成所有类作为“部分”类,这样你就可以自己扩展每个类,而不用担心你的代码被踩到了以防你因为XSD / XML已经改变,所以需要重新生成。
我想这可能听起来很多,但学习曲线实际上非常简单,一旦你安装并正常工作,你就会意识到它是多么愚蠢。这很值得。我发誓。 : - )
答案 2 :(得分:1)
为什么使用手动XML进行配置?现有的app.config
和web.config
架构有什么问题?
答案 3 :(得分:1)
为什么不使用.Settings file?
答案 4 :(得分:1)
您可以按照以下步骤操作:
1)从XML文件生成XSD文件。因为曾经有一个从XML文件推断模式的工具,我忘了它的名字。目前我使用自己的实用程序,它基本上运行此核心例程来读取xml文件并生成相应的xsd:
static void InferSchema(string fileName)
{
XmlWriter writer = null;
XmlSchemaInference infer = new XmlSchemaInference();
XmlSchemaSet sc = new XmlSchemaSet();
string outputXsd = fileName.Replace(".xml", ".xsd");
sc = infer.InferSchema(new XmlTextReader(fileName));
using (writer = XmlWriter.Create(new StreamWriter(outputXsd)))
{
foreach(XmlSchema schema in sc.Schemas())
{
schema.Write(writer);
Console.WriteLine(">> found schema - generated to {0}",
outputXsd);
}
}
}
2)运行xsd.exe以从XSD文件生成可序列化的类。
xsd.exe /c /n:MyNameSpaceHere MyGenerated.xsd
接下来,您可以使用XmlSerializer.Serialize()方法将XML文件读入可序列化类。像这样:
public static void Serialize<T>(T data, TextWriter writer)
{
try
{
XmlSerializer xs = new XmlSerializer(typeof(T));
xs.Serialize(writer, data);
}
catch (Exception e)
{
throw;
}
}
最后,您可以使用XmlSerializer.Deserialize()方法从类中回写XML文件,例如:
public static void Deserialize<T>(out T data, XmlReader reader)
{
try
{
XmlSerializer xs = new XmlSerializer(typeof(T));
data = (T)xs.Deserialize(reader);
}
catch (Exception e)
{
reader.Close();
throw;
}
}
答案 5 :(得分:0)
这称为属性文件。 C#应该类似于Java的Properties类,您可以在其中加载所有属性而无需对其名称进行硬编码。
编辑: 显然没有针对C#的内置属性解析解决方案。但是你可以轻松实现自己的。请参阅here。
答案 6 :(得分:0)
如果您有XSD文件,则可以从中生成类。除了已经提到过的微软的xsd.exe(它已经有很长时间没有更新),还有其他工具可供选择。我正在使用XSD2Code,它允许生成强类型集合,延迟初始化等等。
如果您没有XSD,可以将xsd.exe指向xml文件,它将从中生成XSD。模式通常需要一些工作,但通常是一个很好的起点。
xsd.exe (instance).xml
答案 7 :(得分:0)
您可以使用System.Xml.Serialization - 它非常简单,您可以直接序列化类对象,例如MyCustomClass(它甚至可以保存MyCustomClass公共字段)。
反序列化XML文件将获得MyCustomClass的新实例,因此这样的功能是无价的。
注意一件事:你应该添加你在课堂上使用的每种单一类型,但这很容易。
我附上了一个完整的项目,可以完成您想要的任务。只需更改类和对象即可。 source code
例如(我正在缩短代码):
using System.Xml;
using System.Xml.Serialization;
using System.IO;
[XmlRootAttribute("Vendor")]
class Vendor{
[XmlAttribute]
Product prod;
}
[XmlRootAttribute("Product")]
class Product{
[XmlAttribute]
public string name="";
}
class Test{
Vendor v=new Vendor();
Product p=new Product();
p.name="a cake";
v.prod=p;
//add EVERY SINGLE TYPE you use in the serialized class.
Type[] type_list = { typeof(Product) };
XmlSerializer packer = new XmlSerializer(v.GetType(),type_list);
XmlWriter flusher = XmlWriter.Create(@"c:\bak.xml");
packer.Serialize(flusher, v);
flusher.Close();
XmlReader restorer = XmlReader.Create(@"c:\bak.xml");
Vendor v2 = (Vendor)packer.Deserialize(restorer);
//v2.prod.name is now "cake"
//COOL was my first impression :P
}