我在文件中有以下XML。
<config>
<appSettings>
<DEV>
<INDIR>\\serv1\TEST\INDIR\</INDIR>
<OUTDIR>\\serv1\TEST\OUTDIR\</OUTDIR>
<LOGDIR>\\serv1\TEST\LOGDIR\</LOGDIR>
</DEV>
<STAGE>
<INDIR>\\serv1\INDIR\</INDIR>
<OUTDIR>\\serv1\OUTDIR\</OUTDIR>
<LOGDIR>\\serv1\LOGDIR\</LOGDIR>
</STAGE>
<PROD>
<INDIR>\\serv2\INDIR\</INDIR>
<OUTDIR>\\serv2\OUTDIR\</OUTDIR>
<LOGDIR>\\serv2\LOGDIR\</LOGDIR>
</PROD>
</appSettings>
<execSettings>
<DEV>
<FILTER>*.TXT</FILTER>
<RETENTION>7</RETENTION> <!-- in days -->
</DEV>
<STAGE>
<FILTER>*.TXT</FILTER>
<RETENTION>14</RETENTION> <!-- in days -->
</STAGE>
<PROD>
<FILTER>*.TXT</FILTER>
<RETENTION>60</RETENTION> <!-- in days -->
</PROD>
</execSettings>
</config>
使用名为'platform'的变量保存字符串“DEV”或“STAGE”或“PROD”,我希望
从appSettings和execSettings中的相应部分获取该平台的元素
并将它们设置在下面的类中。
public class config
{
public string InDir { get; set; }
public string OutDir { get; set; }
public string LogDir { get; set; }
public string Filter { get; set; }
public Int32 Retention { get; set; }
}
这是代码尝试。如评论中所示,对于节点
,我的计数为零
名单。对此有任何帮助表示赞赏。
XmlDocument xDoc = new XmlDocument();
string platform = "DEV";
IEnumerator ienum;
try
{
xDoc.Load(xmlFile);
string xPath1 = "appSettings/" + platform;
string xPath2 = "execSettings/" + platform;
XmlNodeList appElements = xDoc.GetElementsByTagName("xPath1"); //count = 0
XmlNodeList execElements = xDoc.GetElementsByTagName("xPath2"); //count = 0
config cSet = new config();
ienum = appElements.GetEnumerator(); //null
while (ienum.MoveNext())
{
XmlNode INDIR = (XmlNode)ienum.Current;
XmlNode OUTDIR = (XmlNode)ienum.Current;
XmlNode LOGDIR = (XmlNode)ienum.Current;
cSet.InDir = INDIR.InnerText;
cSet.OutDir = OUTDIR.InnerText;
cSet.LogDir = LOGDIR.InnerText;
}
ienum = execElements.GetEnumerator(); //null
while (ienum.MoveNext())
{
XmlNode FILTER = (XmlNode)ienum.Current;
XmlNode RETENTION = (XmlNode)ienum.Current;
cSet.Filter = FILTER.InnerText;
cSet.Retention = RETENTION.InnerText;
}
根据我收到的反馈(感谢所有人),这里是一个更新的代码发布,浓缩,但我仍然看到XmlNodeList的count = 0。
XmlDocument xDoc = new XmlDocument();
string platform = "DEV";
try
{
xDoc.Load(xmlFile);
string xPath1 = "appSettings/" + platform;
XmlNodeList appElements = xDoc.SelectNodes("xPath1"); //count = 0
config cSet = new config();
foreach (XmlNode node in appElements)
{
cSet.InDir = node["./INDIR"].InnerText;
}
}
catch (Exception ex)
{
ADHOC.func.RecordTo_LogFile("XML||Load_Failure");
throw (ex);
}
答案 0 :(得分:1)
您正在处理XPath查询,因此请改用SelectNodes
。
string xPath1 = "//appSettings/" + platform;
string xPath2 = "//execSettings/" + platform;
XmlNodeList appElements = xDoc.SelectNodes(xPath1);
XmlNodeList execElements = xDoc.SelectNodes(xPath2);
此外,循环也无法正确检索节点数据。
foreach (XmlNode appNode in appElements)
{
XmlNode INDIR = appNode.selectSingleNode("./INDIR");
XmlNode OUTDIR = appNode.selectSingleNode("./OUTDIR");
XmlNode LOGDIR = appNode.selectSingleNode("./LOGDIR");
cSet.InDir = INDIR.InnerText;
cSet.OutDir = OUTDIR.InnerText;
cSet.LogDir = LOGDIR.InnerText;
}
答案 1 :(得分:1)
如何以完全不同的方式解决问题:相反,如果这些Prod / Dev节点使用 XML Transformations 。它们完全受MSBUild支持,并使配置文件更加清晰。
答案 2 :(得分:0)
我为那些感兴趣的人制定了解决方案......
XmlDocument xDoc = new XmlDocument();
string platform = "DEV";
try
{
xDoc.Load(xmlFile);
string xPath1 = "descendant::appSettings/" + platform;
XmlNodeList appElements = xDoc.SelectNodes(xPath1);
config cSet = new config();
foreach (XmlNode node in appElements)
{
cSet.InDir = node.SelectSingleNode("./INDIR").InnerText;
cSet.OutDir = node.SelectSingleNode("./OUTDIR").InnerText;
cSet.LogDir = node.SelectSingleNode("./LOGDIR").InnerText;
}
}
catch (Exception ex)
{
ADHOC.func.RecordTo_LogFile("XML||Load_Failure");
throw (ex);
}
答案 3 :(得分:0)
我不确定你对上面的配置类有多强烈的束缚,但我强烈建议远离XPath的值。我对自定义配置文件的偏好(除非您使用的是.NET配置管理器)将使用XmlSerialization,它为您提供基于强类型对象的方法来解决您的问题。为了满足上面的XML文件,你必须改变你的配置类,但可能不是它的接口:
根据您提供的内容的记事本副本,这是一个艰难的过程:
[XmlRoot("config")]
public class Configuration
{
[XmlElement("appSettings")]
public AppSettings ApplicationSettings
{
get;
set;
}
[XmlElement("execSettings")]
public ExecSettings ExecutionSettings
{
get;
set;
}
}
[XmlRoot("appSettings")] // Not really necessary this xmlroot
public class AppSettings
{
[XmlElement("DEV")]
public EnvironmentSetting Development
{
get;
set;
}
[XmlElement("STAGE")]
public EnvironmentSetting Staging
{
get;
set;
}
[XmlElement("PROD")]
public EnvironmentSetting Production
{
get;
set;
}
}
[XmlRoot("execSettings")] // Not really necessary this xmlroot
public class ExecSettings
{
[XmlElement("DEV")]
public ExecutionSetting Development
{
get;
set;
}
[XmlElement("STAGE")]
public ExecutionSetting Staging
{
get;
set;
}
[XmlElement("PROD")]
public ExecutionSetting Production
{
get;
set;
}
}
public class EnvironmentSetting
{
[XmlElement("INDIR")]
public string InDirectory
{
get;
set;
}
[XmlElement("OUTDIR")]
public string OutDirectory
{
get;
set;
}
[XmlElement("LOGDIR")]
public string LogDirectory
{
get;
set;
}
}
public class ExecutionSetting
{
[XmlElement("FILTER")]
public string Filter
{
get;
set;
}
[XmlElement("RETENTION")]
public string Retention
{
get;
set;
}
}
填充此类对象后,您可以使用System.Xml.Serialization命名空间中的XmlSerializer对其进行序列化
Configuration config = new Configuration ();
XmlSerializer serializer = new XmlSerializer(typeof(Configuration));
string resultXml = serializer.Serialize(settings);
反之亦然
配置config =(配置)serializer.Deserialize(appConfigText); config.AppSettings.Development.InDir = ... e.t.c。
XmlSerializers非常适合强类型配置。