【问题标题】:Readout XML-File (Only from Project)读出 XML 文件(仅来自项目)
【发布时间】:2014-04-22 16:05:06
【问题描述】:

我必须从我的本地 Visual Studio 2013 项目结构中读取一个 XML 文件(包含现有内容),而不是从硬盘目录(如大多数教程/指南中所述,我在最后 2小时...)。在读出过程之后,我必须在其中搜索一些标签名称。

我必须这样做,因为要求是,指定的本地 XML 文件不应出现在输出目录中的构建过程之后...

那我该怎么做呢?

================================================ ====================================

这是我的 AccessData.xml 文件(在项目目录中:“LinqToXML_Example/AccessData.xml”):

<?xml version="1.0" encoding="utf-8"?>

  <Clients>


    <Client>

        <Username>Administrator</Username>

        <Password>Admin-Password</Password>

        <Settings>
          <Item1>Admin-Setting 1</Item1>
          <Item2>Admin-Setting 2</Item2>
          <Item3>Admin-Setting 3</Item3>
        </Settings>

    </Client>



    <Client>

        <Username>Service</Username>

        <Password>Srv-Password</Password>

        <Settings>
          <Item1>Srv-Setting 1</Item1>
          <Item2>Srv-Setting 2</Item2>
          <Item3>Srv-Setting 3</Item3>
        </Settings>

    </Client>



    <Client>

        <Username>Customer</Username>

        <Password>Cust-Password</Password>

        <Settings>
          <Item1>Cust-Setting 1</Item1>
          <Item2>Cust-Setting 2</Item2>
          <Item3>Cust-Setting 3</Item3>
        </Settings>

    </Client>


  </Clients>

这是我的 Program.cs 文件:

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

namespace LinqToXML_Example
{
    public class Program
    {


        public static string SearchForUsername(string username, XElement clients)
        {

            var userName = from p in clients.Elements()
                            where p.Element("Username").Value == username
                            select p.Element("Username").Value;

            foreach (var p in userName)
            {
                return p + " found!";
            }

            return "User '" + username + "' does not exist!";
        }



        public static bool IsUsernameExisting(string username, XElement clients)
        {
            var userName = from p in clients.Elements()
                            where p.Element("Username").Value == username
                            select p.Element("Username").Value;

            foreach (var p in userName)
            {
                return true;
            }

            return false;
        }



        public static string SearchForUsernamePassword(string username, XElement clients)
        {

            if (IsUsernameExisting(username, clients))
            {
                var password = from p in clients.Elements()
                                where p.Element("Username").Value == username
                                select p.Element("Password").Value;

                foreach (var p in password)
                    return "The password of client " + username + " is: " + p;
            }

            return "Cannot get the username's password, because of a wrong Username!";
        }



        public static List<string> ReadUserSettings(string username, XElement clients)
        {

            List<string> settingsList = new List<string>();


            if (IsUsernameExisting(username, clients))
            {
                var setting = from s in clients.Elements()
                                where s.Element("Username").Value == username
                                select s.Element("Settings");

                foreach (var p in setting)
                {
                    settingsList.Add(p.Element("Item1").Value);
                    settingsList.Add(p.Element("Item2").Value);
                    settingsList.Add(p.Element("Item3").Value);
                }

                return settingsList;
            }


            var errorMsg = "Cannot get the username's settings, because of a wrong Username!";
            settingsList.Add(errorMsg);

            return settingsList;
        }





        public static void Query(string username, XElement clients)
        {
            // Search for specific Username:
            Console.WriteLine("Search for Client " + "'" + username + "' (based on Usernames):");

            string result = SearchForUsername(username, clients);
            Console.WriteLine(result);


            Console.WriteLine("");


            // Search for Password of Client:
            Console.WriteLine("Search for Password of Client " + "'" + username + "':");

            result = SearchForUsernamePassword(username, clients);
            Console.WriteLine(result);


            Console.WriteLine("");


            // Readout the Settings of Client:
            Console.WriteLine("Readout the Settings of Client " + "'" + username + "':");

            List<string> resultList = new List<string>();
            resultList = ReadUserSettings(username, clients);

            if (resultList.Count != 1)
            {
                for (int i = 0; i < resultList.Count(); i++)
                {
                    var itemcounter = i + 1;
                    Console.WriteLine("Item" + itemcounter + ": " + resultList.ElementAt(i));
                }
            }

            else Console.WriteLine(resultList.ElementAt(0));



            Console.Read();
        }




        static void Main()
        {

            var asm = Assembly.GetExecutingAssembly();

  // Bug fix: "AccessData.xml" has to be changed to: "LinqToXML_Example.AccessData.xml" 
            var textStream = asm.GetManifestResourceStream("AccessData.xml");

       // Bug fix: Has to be changed to: var xmlReader = new XmlTextReader(textStream);
            var xmlReader = new XmlReader(textStream);

            XElement clients = XElement.Load(xmlReader);

            Query("Administrator", clients);
        }
    }
}

我已将 AccessData.xml 文件的属性更改为:

Build Action = "Resource" // Bug fix: Has to be changed to: 'Embeded Resource'

Copy to output directory = "Never"

不幸的是,我无法访问我的 xml 文件 :((

【问题讨论】:

  • 将内容存储到程序中的简单字符串中并直接使用它而不是使用资源会不会更容易?

标签: c# xml project local


【解决方案1】:

大致扫描了您的代码,以下行似乎是问题所在:

var textStream = asm.GetManifestResourceStream("AccessData.xml");

默认情况下,资源名称以项目的默认命名空间为前缀。此外,该文件所在的项目文件夹也包含在名称中。因此,在您的情况下,资源名称很可能是 “LinqToXML_Example.AccessData.xml” 而不是“AccessData.xml”。

此外,您应该将构建操作设置为 Embedded Resource

如果要查找项目文件中包含的所有资源名称,可以使用此代码并在调试时检查返回值:

string[] names = asm.GetManifestResourceNames();

详情请参阅link

【讨论】:

  • 好的,但我的“Program.cs”文件中已经有 2 个错误。编译器抱怨:“无法在此处访问受保护的构造函数 'XmlReader'”。我该如何解决?
  • @phonopunk:您不能直接实例化 XmlReader。将 new XmlReader(textStream); 更改为 new XmlTextReader(textStream); 应该会有所帮助。
  • 非常感谢,先生! :) 我很高兴你的回答!
猜你喜欢
  • 2014-10-30
  • 1970-01-01
  • 2018-02-13
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
相关资源
最近更新 更多