【问题标题】:Read xml file using System.XML namespace使用 System.XML 命名空间读取 xml 文件
【发布时间】:2013-09-09 16:28:01
【问题描述】:

我想使用我自己的 xml 代码(不是 linq to xml)读取 App.config 文件的 <appSettings> 部分:

这是我的 app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   
<appSettings>
    <add key="driver" value="C:/"/>
    <add key="daysToExpire" value="0"/>
    <add key="Interval" value="5000"/>
</appSettings>
<system.net>
    <mailSettings >
        <smtp>
            <network enableSsl="false" 
                     port="25"
                     host="smtp.gmail.com"
                     defaultCredentials="false"
                     />

        </smtp>
    </mailSettings>
</system.net>

我的 c# 代码:

XmlDocument doc = new XmlDocument();
doc.Load(
    Path.Combine(AppDomain.CurrentDomain.BaseDirectory,    "config.xml")
);

XmlNodeList appSettings = doc.SelectNodes("/configuration/appSettings/add");

Driver = appSettings[0].Attributes[0].Value;
Interval = Convert.ToInt16(appSettings[2].Value);
DaysToExpire = Convert.ToInt16(appSettings[1].Value);

appSettings 有 3 种模式,但我没有设法访问每一种。

我还想阅读system.net 部分。

【问题讨论】:

  • 你不喜欢 ConfigurationManager.AppSettings 吗?
  • 是的,但我更喜欢用这种方式来学习阅读 xml。
  • @senyorToni 我认为现在学习使用 LINQ 阅读 xml 会更好。十年前学习 XmlDocument 很有趣。 AccessDenied 也是正确的 - 最好将 ConfigurationManager 用于此类任务

标签: c# .net xml system.xml


【解决方案1】:

LINQ to XML方式:

var xDoc = XDocument.Load("Input.txt");

var appSettings = xDoc.Root.Element("appSettings");
var driver = (string)appSettings.Elements("add")
                                .First(x => (string)x.Attribute("key") == "driver")
                                .Attribute("value");
var daysToExpire = (string)appSettings.Elements("add")
                                      .First(x => (string)x.Attribute("key") == "daysToExpire")
                                      .Attribute("value");
var interval = (string)appSettings.Elements("add")
                                  .First(x => (string)x.Attribute("key") == "Interval")
                                  .Attribute("value");

您需要在文件顶部出现using System.Linqusing System.Xml.Linq 才能使其工作。

但说实话:你应该使用AppSettings,因为它就是为此而设计的。

【讨论】:

    【解决方案2】:

    让我解释一下为什么手动解析 appSettings 不是一个好主意。除了add 元素appSettings 可以包含clearremove 元素,它们会影响之前定义的设置。所以,有以下部分:

    <appSettings>
      <add key="driver" value="C:/"/>
      <clear/>
      <add key="daysToExpire" value="0"/>    
      <add key="Interval" value="5000"/>
      <remove key="daysToExpire"/>
    </appSettings>
    

    您将只为您的应用程序定义一个设置(间隔)。如果您尝试获取所有 add 元素,您将得到不正确的设置(所有三个元素都将在字典中):

    var configPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
    var xdoc = XDocument.Load(configPath);
    var appSettings = xdoc.Root.Element("appSettings").Elements("add")
                          .ToDictionary(a => (string)a.Attribute("key"),
                                        a => (string)a.Attribute("value"));
    

    正确的解析如下所示:

    var appSettings = new Dictionary<string, string>();
    foreach(var e in xdoc.Root.Element("appSettings").Elements())
    {
        switch(e.Name.LocalName)
        {
            case "add":
                appSettings.Add((string)e.Attribute("key"), 
                                (string)e.Attribute("value"));
                break;
            case "clear":
                appSettings.Clear();
                break;
            case "remove":
                appSettings.Remove((string)e.Attribute("key"));
                break;
        }
    }
    

    另一方面,ConfigurationManager 已经存在,它可以正确解析应用程序设置。以下代码将打印出单个 Interval 设置:

    foreach(string key in ConfigurationManager.AppSettings)
        Console.WriteLine("{0}: {1}", key, settings[key]);
    

    另外请记住,您的应用程序的实际设置也将包含来自machinne.config 文件的设置。 ConfigurationManager 也会为您获取这些设置。

    【讨论】:

      【解决方案3】:

      如果您只想读取 app.config 设置,请使用配置管理器。如果您正在尝试学习如何使用 XmlDocument,您会遇到一些问题。

      1) 在一般情况下,您确实不应该依赖于 XML 文档中节点的顺序,如果您根据 XML 内容进行解析,您将拥有更稳定的代码。这不是您的实际问题。

      2) Considering the node  <add key="daysToExpire" value="0"/>  
      

      这实际上是一个 XmlElement 节点。它包含 2 个 XmlAttribute 节点。它没有值。实际上,en XmlElement 节点永远不会有值(.Value 属性将始终为空)。 XmlElement 中的“值”将是 .InnerText(或 .InnerXml)属性。

      如果您查看您的代码,您会正确地将驱动程序值读取为属性,但对于其他两个节点您没有这样做。您仍然存在根据索引而不是属性名称检索属性的问题。使用名称是一种更稳定的解析技术。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-30
        • 2015-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多