【问题标题】:Read simple XML file and save values into variable [duplicate]读取简单的 XML 文件并将值保存到变量中 [重复]
【发布时间】:2014-05-05 02:38:54
【问题描述】:

我对 C# 还很陌生。我在网上搜索了最后几天以找到解决我的问题的方法,但我能找到的都太复杂了。我想要做什么:读取一个简单的 XML 文件并将每个值保存到我可以在我的 C# 程序中使用的变量中。这是 XML:

<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <General>
    <Option1>66</Option1>
    <Option2>78</Option2>
    <Checkbox1>False</Checkbox1>
  </General>
  <Advanced>
    <AdvOption1>22</AdvOption1>
  </Advanced>
</Settings>

所以,要明确我想要实现的目标:我想将“66”、“78”和“False”保存到变量中。永远不会有 2 个同名的 XML 节点。我无法真正显示任何 C# 代码,因为我尝试了很多不同的 sn-ps,但它们都使用了循环,因为它正在读取多个“标题”或“作者”。我只是觉得它太简单了,这就是为什么网络上没有任何东西:(

【问题讨论】:

  • Duplicate 展示了在 .Net 中解析 XML 的大多数方法。如果您有唯一的节点,请不要使用循环来查找特定的子节点...
  • Gleb 的回答对我来说很好

标签: c# xml


【解决方案1】:

有几种方法可以实现您的要求。这是一个使用 Xlinq 的示例。您还可以使用基于 xpath 的解决方案(请参阅Link 了解更多信息)。

该解决方案使用 linq 样式语法查询 XML 文件,请注意,您需要做出一些关于处理缺失部分或重复部分的决定,我选择了一个解决方案,但您需要确保它符合您的应用程序需要.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            // Get the XML doc from a file, similarly you can get it from a string or stream.
            var doc = XDocument.Load("file.xml");

            // Use linq style to get to the first Settings element or throw
            var settings = doc.Elements("Settings").Single().Elements();

            // Get root nodes for the settings type, if there is more than one ignore the rest and grab the first.
            // Change the logic to throw or combine to match the rules for your app
            var generalOptions = settings.FirstOrDefault(e => e.Name.LocalName == "General");
            var advancedOptions = settings.FirstOrDefault(e => e.Name.LocalName == "Advanced");

            var generalSettings = ExtractOptions(generalOptions);
            var advancedSettings = ExtractOptions(advancedOptions);
        }

        private static Settings ExtractOptions(XElement rootElement)
        {
            var settings = new Settings();

            if (rootElement != null)
            {
                var elements = rootElement.Elements();

                settings.Options = elements.Where(e => e.Name.LocalName.IndexOf("Option", StringComparison.OrdinalIgnoreCase) >= 0)
                                           .Select(e => int.Parse(e.Value))
                                           .ToArray();

                settings.CheckBoxes = elements.Where(e => e.Name.LocalName.StartsWith("CheckBox", StringComparison.OrdinalIgnoreCase))
                                              .Select(e => bool.Parse(e.Value))
                                              .ToArray();
            }

            return settings;
        }

        public class Settings
        {
            public int[] Options { get; set; }
            public bool[] CheckBoxes { get; set; }
        }
    }
}

【讨论】:

    【解决方案2】:

    尝试使用这样的东西:

    int opt1, opt2, advOpt1;
    bool check;
    
    XmlDocument doc = new XmlDocument();
    doc.Load("YourXMLFile.xml");
    
    opt1 = Convert.ToInt32(doc.SelectSingleNode("Settings/General/Option1").InnerText);
    opt2 = Convert.ToInt32(doc.SelectSingleNode("Settings/General/Option2").InnerText);
    check = Convert.ToBoolean(doc.SelectSingleNode("Settings/General/Checkbox1").InnerText);
    advOpt1 = Convert.ToInt32(doc.SelectSingleNode("Settings/Advanced/AdvOption1").InnerText);
    

    【讨论】:

    • 这正是我所需要的,非常感谢您,先生
    【解决方案3】:

    虽然您可以使用正则表达式等破解它,但如果您正确解析 XML,从长远来看,您会变得更好。

    看看XDocument。这是一个解析来自https://github.com/slicify/nslicify的 XML 格式的 Web 响应的示例

    XML

    <BidInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://secure.slicify.com">
      <BidID>32329</BidID>
      <BookingID>131179</BookingID>
      <Active>true</Active>
      <MaxPrice>0.01</MaxPrice>
      <MinECU>20</MinECU>
      <MinRAM>1024</MinRAM>
      <Country/>
      <Bits>64</Bits>
      <Deleted>false</Deleted>
      <IncLowBW>false</IncLowBW>
      <ScriptID>153</ScriptID>
      <UserData/>
    </BidInfo>
    

    解析器

        private BidInfo BidInfoParser(XDocument doc)
        {
            BidInfo info = null;
    
            //get the first record in the result set
            XContainer c1 = (XContainer)(doc);
            XContainer c2 = (XContainer)(c1.FirstNode);
    
            //loop through fields
            foreach (XNode node in c2.Nodes())
            {
                XElement el = (XElement)node;
                string key = el.Name.LocalName;
                string value = el.Value;
    
                //little hack to only set BidInfo if there are some values
                if(info == null)
                    info = new BidInfo();
    
                if (key.Equals("Active", StringComparison.InvariantCultureIgnoreCase))
                    info.Active = Convert.ToBoolean(value);
                else if (key.Equals("BidID", StringComparison.InvariantCultureIgnoreCase))
                    info.BidID = Convert.ToInt32(value);
                else if (key.Equals("Bits", StringComparison.InvariantCultureIgnoreCase))
                    info.Bits = Convert.ToInt32(value);
                else if (key.Equals("BookingID", StringComparison.InvariantCultureIgnoreCase))
                    info.BookingID = Convert.ToInt32(value);
                else if (key.Equals("Country", StringComparison.InvariantCultureIgnoreCase))
                    info.Country = value;
                else if (key.Equals("MaxPrice", StringComparison.InvariantCultureIgnoreCase))
                    info.MaxPrice = Convert.ToDecimal(value);
                else if (key.Equals("MinECU", StringComparison.InvariantCultureIgnoreCase))
                    info.MinECU = Convert.ToInt32(value);
                else if (key.Equals("MinRAM", StringComparison.InvariantCultureIgnoreCase))
                    info.MinRAM = Convert.ToInt32(value);
                else if (key.Equals("Deleted", StringComparison.InvariantCultureIgnoreCase))
                    info.Deleted = Convert.ToBoolean(value);
                else if (key.Equals("IncLowBW", StringComparison.InvariantCultureIgnoreCase))
                    info.IncludeLowBandwidth = Convert.ToBoolean(value);
                else if (key.Equals("scriptID", StringComparison.InvariantCultureIgnoreCase))
                    info.ScriptID = Convert.ToInt32(value);
                else if (key.Equals("userdata", StringComparison.InvariantCultureIgnoreCase))
                    info.UserData = value;
                else
                    throw new Exception("Unknown tag in XML:" + key + " = " + value);
            }
            return info;
        }
    
        /// <summary>
        /// Contains information about this bid.
        /// </summary>
        public class BidInfo
        {
            public int BidID { get; set; }
            public int BookingID { get; set; }
            public bool Active { get; set; }
            public decimal MaxPrice { get; set; }
            public int MinECU { get; set; }
            public int MinRAM { get; set; }
            public string Country { get; set; }
            public int Bits { get; set; }
            public bool Deleted { get; set; }
            public bool IncludeLowBandwidth { get; set; }
            public int ScriptID { get; set; }
            public string UserData { get; set; }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-25
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2019-11-01
      • 2019-01-30
      • 1970-01-01
      相关资源
      最近更新 更多