我有一个名为 config.xml 的独立 XML 文件,它与我的应用程序一起使用,它基本上包含两个部分:
1) 全局设置 2) 服务器列表,包括设置
基本上,全局设置将包含我的程序将用于每个服务器列表的数据库用户名和数据库密码。
服务器列表条目包含服务器列表,以及一些文件名、数据库用户名和数据库密码。这里唯一重要的是,如果我在服务器列表中指定用户名/密码,那么它将使用它而不是全局数据库用户名和密码。或者,换一种说法,如果在 serverwr 列表条目中未定义数据库用户名和密码,它将使用全局数据库用户名密码。
我的程序基本上循环遍历 xml 配置文件并对每个 DB2 服务器执行一些数据库查询,处理信息并创建报告。它今天有效,但我确实有一些问题......
1) 每次我向我的 XML 配置文件添加一个新元素时,我都必须为我创建的每个节点添加它,否则我会收到 XML 解析错误。
2) 我想对我的配置 XML 文件进行分类,而不是将所有内容集中在同一个节点中并包含空元素。
示例 XML 如下:
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<Global>
<OutputFolder>C:\DATA\Configs\DB2\</OutputFolder>
<DBUser>DB2ADMIN</DBUser>
<DBPassword>%SecretPassword%</DBPassword>
<FTPFiles>false</FTPFiles>
<FTPTcpIp>127.0.0.1</FTPTcpIp>
<FTPUser>FTPLogin1</FTPUser>
<FTPPassword>P@ssw0rd</FTPPassword>
<FTPRemoteFolder>/configs</FTPRemoteFolder>
</Global>
<Servers>
<Server enabled="true">
<Category>Report1</Category>
<TcpIp>192.168.26.107</TcpIp>
<Database>SampleData</Database>
<User></User>
<Password></Password>
<Report1FileNameList>List1.txt</Report1FileNameList>
<Report1FileNameRoutes>Routes1.txt</Report1FileNameRoutes>
<Report1FileNameRouteTimeouts>Timeouts1.txt</Report1FileNameRouteTimeouts>
<Report1FileNameEndpoints></Report1FileNameEndpoints>
<Report2FilenameServers></Report2FilenameServers>
<Report2FilenameRoutingGroup></Report2FilenameRoutingGroup>
</Server>
<Server enabled="true">
<Category>Report1</Category>
<TcpIp>192.168.26.107</TcpIp>
<Database>SampleDataB</Database>
<User></User>
<Password></Password>
<Report1FileNameList>List1.txt</Report1FileNameList>
<Report1FileNameRoutes>Routes1.txt</Report1FileNameRoutes>
<Report1FileNameRouteTimeouts>Timeouts1.txt</Report1FileNameRouteTimeouts>
<Report1FileNameEndpoints></Report1FileNameEndpoints>
<Report2FilenameServers></Report2FilenameServers>
<Report2FilenameRoutingGroup></Report2FilenameRoutingGroup>
</Server>
<Server enabled="true">
<Category>Report2</Category>
<TcpIp>192.168.26.107</TcpIp>
<Database>SampleDataE</Database>
<User></User>
<Password></Password>
<Report1FileNameList></Report1FileNameList>
<Report1FileNameRoutes></Report1FileNameRoutes>
<Report1FileNameRouteTimeouts></Report1FileNameRouteTimeouts>
<Report1FileNameEndpoints>Endpoints2.txt</Report1FileNameEndpoints>
<Report2FilenameServers>Servers2.txt</Report2FilenameServers>
<Report2FilenameRoutingGroup>Groups2.txt</Report2FilenameRoutingGroup>
</Server>
<Server enabled="true">
<Category>Report2</Category>
<TcpIp>192.168.26.108</TcpIp>
<Database>SampleDatabase1_D</Database>
<User></User>
<Password></Password>
<Report1FileNameList></Report1FileNameList>
<Report1FileNameRoutes></Report1FileNameRoutes>
<Report1FileNameRouteTimeouts></Report1FileNameRouteTimeouts>
<Report1FileNameEndpoints>Endpoints2.txt</Report1FileNameEndpoints>
<Report2FilenameServers>Servers2.txt</Report2FilenameServers>
<Report2FilenameRoutingGroup>Groups1.txt</Report2FilenameRoutingGroup>
</Server>
</Servers>
示例代码如下:
// load XML file
try
{
// Config/Global
System.Xml.XPath.XPathDocument doc = new System.Xml.XPath.XPathDocument(@"config.xml");
foreach (System.Xml.XPath.XPathNavigator child in doc.CreateNavigator().Select("Config/Global"))
{
xml_global_outputFolder = child.SelectSingleNode("OutputFolder").Value;
xml_global_DBuser = child.SelectSingleNode("DBUser").Value;
xml_global_DBpassword = child.SelectSingleNode("DBPassword").Value;
xml_global_FTPFiles = bool.Parse(child.SelectSingleNode("FTPFiles").Value);
xml_global_FTPTcpIp = child.SelectSingleNode("FTPTcpIp").Value;
xml_global_FTPUser = child.SelectSingleNode("FTPUser").Value;
xml_global_FTPPassword = child.SelectSingleNode("FTPPassword").Value;
xml_global_FTPRemoteFolder = child.SelectSingleNode("FTPRemoteFolder").Value;
}
// Config/Servers
//System.Xml.XPath.XPathDocument doc = new System.Xml.XPath.XPathDocument(@"config.xml");
foreach (System.Xml.XPath.XPathNavigator child in doc.CreateNavigator().Select("Config/Servers/*"))
{
//string xml_enabled = child.GetAttribute("Enabled", "");
string xml_category = child.SelectSingleNode("Category").Value;
string xml_tcpip = child.SelectSingleNode("TcpIp").Value;
string xml_database = child.SelectSingleNode("Database").Value;
string xml_user = child.SelectSingleNode("User").Value;
string xml_password = child.SelectSingleNode("Password").Value;
Console.WriteLine("Connecting to {0} using database {1} for {2} information...", xml_tcpip, xml_database, xml_category);
// if node user value is empty, use global
if (xml_user == string.Empty)
{
DB2_user = xml_global_DBuser;
}
else
{
DB2_user = xml_user;
}
// if node password value is empty, use global
if (xml_password == string.Empty)
{
DB2_password = xml_global_DBpassword;
}
else
{
DB2_password = xml_password;
}
string txtFilename = string.Empty;
string csvFilename = string.Empty;
switch (xml_category.ToUpper())
{
case "SAMPLE":
txtFilename = Path.Combine(xml_global_outputFolder, @"EMPLOYEE.csv");
csvFilename = Path.Combine(xml_global_outputFolder, Path.GetFileNameWithoutExtension(@"EMPLOYEE.csv"));
ExecuteQuery(xml_category, "SAMPLE", xml_tcpip, DB2_user, DB2_password, xml_database, csvFilename, txtFilename, option_debug);
break;
}
Console.WriteLine("");
}
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e.Message);
Environment.Exit(1);
}
Environment.Exit(0);
}
我想理想情况下,我想创建特定于节点的配置,如果元素为空白,代码应该能够处理丢失的元素或空元素。也许使用类别的属性,而不是?就像是:
<Config>
<Global>
<OutputFolder></OutputFolder>
<DBUser></DBUser>
<DBPassword><DBPassword>
</Global>
<Servers category="Report1">
<Server>
<TcpIP>whatever</TcpIP>
<User>whatever></User>
<Password>whatever></Password>
</Server>
<Server>
<TcpIP>whatever</TcpIP>
<User>whatever></User>
<Password>whatever></Password>
</Server>
<Server>
<TcpIP>whatever</TcpIP>
<User>whatever></User>
<Password>whatever></Password>
</Server>
</Server>
<Servers category="Report2">
<Server>
<TcpIP>whatever</TcpIP>
<User>whatever></User>
<Password>whatever></Password>
</Server>
<Server>
<TcpIP>whatever</TcpIP>
<User>whatever></User>
<Password>whatever></Password>
</Server>
<Server>
<TcpIP>whatever</TcpIP>
<User>whatever></User>
<Password>whatever></Password>
</Server>
</Server>
<Servers category="AccessList">
<Server>
<TcpIP>whatever</TcpIP>
<Database>whatever></Database>
<Active>whatever</Active>
</Server>
<Server>
<TcpIP>whatever</TcpIP>
<Database>whatever></Database>
<Active>whatever</Active>
</Server>
<Server>
<TcpIP>whatever</TcpIP>
<Database>whatever></Database>
<Active>whatever</Active>
</Server>
</Server>
</Config>