在C#中加载XML文件路径

9

我正在尝试加载一个XML文件,它位于我的项目文件夹中(使用Visual Studio 2012)。

结构如下:

solutionRoot\
-  service\
--   ServiceClass.cs
--   AppValues.xml  <-- this is the file I want to load

在我的ServiceClass中,我正在尝试使用以下代码从XML文件中读取:
public String GetXmlElement(String elementName)
{
    [....]
    XDocument document = XDocument.Load(@"\service\AppValues.xml");
    [...]
}

当我尝试测试代码时,出现以下错误:

Test method PandaTests.ServiceTest.ReadXmlCanReadXml threw exception: 
System.IO.DirectoryNotFoundException: Could not find a part of the path 
'C:\Users\MyName\Documents\GitHub\project\Project22\PandaTests\bin\Debug\service\AppValues.xml'.

显然我的问题出在路径上,但我无法弄清如何正确获取相对路径。我已经查看了stackoverflow上的其他问题,但其中许多问题似乎过于复杂。有没有一种简单的方法可以加载XML文件而不必给出绝对路径?


你的XML文件属性是否显示为“复制新文件”或“始终复制”?否则,XML文件将不会被复制到输出路径。 - Marvin Smit
你的目标是哪种类型的应用程序? - Habib
@MarvinSmit - 它被设置为资源,并且“复制到输出目录”设置为“始终复制”。 - Tobias Roland
@Habib - 这是一个WPF项目的一部分 - 实际上这只是其中非常小的一部分,但到目前为止它已经让我头疼了。 - Tobias Roland
从字符串中删除前导“\”。通常具有该值与c:\相同。 - gunr2171
7个回答

16

当VS运行您的程序时,您的工作目录设置为Debug/Release文件夹而不是您的解决方案根目录。

我知道有一些选项...

  1. 使用绝对路径,但您不希望这样做。
  2. 将文件设置为在构建时复制到工作目录中。您可以通过修改解决方案浏览器中文件的属性来实现此操作。感谢下面评论中的T.Roland:将复制到输出目录设置为如果较新则复制并将生成操作设置为嵌入的资源
  3. 修改解决方案的工作目录为解决方案根目录。此线程提供了不同的方法来实现这一点。

4
我建议扩展第二点(要设置哪些属性)的编辑,基本上包括: A)将复制到输出目录设置为仅在更新时复制; B)将生成操作设置为嵌入式资源; C)现在可以使用XDocument.Load(@"service\AppValues.xml")加载该文件。 - Tobias Roland

4

我曾遇到同样的问题并使用 "Server.MapPath" 解决了它。

例如:

string path=Server.MapPath("~/service/AppValues.xml");

XDocument document = XDocument.Load(path);

希望能有所帮助。

2

在Visual Studio中打开AppValues.xml文件的属性。将“复制到输出目录”更改为“如果较新则复制”,然后构建项目。


0

我用两个步骤解决了这个问题。我正在使用MVC,我必须在一个类文件中使用它。

1)字符串路径

=HttpContext.Current.Server.MapPath("~/App_Data/yourxmlfilename.xml");
XDocument doc = XDocument.Load(path);

2) 更改 XML 文件属性

生成操作:内容
复制到输出目录:始终复制


0
将xml文件的构建操作设置为“嵌入式资源”,然后使用以下代码进行引用。
private static UnmanagedMemoryStream GetResourceStream(string resName)
{
    var assembly = Assembly.GetExecutingAssembly();
    var strResources = assembly.GetName().Name + ".g.resources";
    var rStream = assembly.GetManifestResourceStream(strResources);
    var resourceReader = new ResourceReader(rStream);
    var items = resourceReader.OfType<DictionaryEntry>();
    var stream = items.First(x => (x.Key as string) == resName.ToLower()).Value;
    return (UnmanagedMemoryStream)stream;
}

    var file = GetResourceStream("appValues.xml");

0

将文件添加到 Visual Studio 项目时,默认情况下不会复制到生成的输出中。因此,您需要设置为复制文件或手动执行。

要设置文件自动复制,请在“解决方案资源管理器”中选择该文件,右键单击并选择属性。更新“复制到输出目录”的值为“始终复制”。这将确保文件的副本在结果解决方案的子文件夹中在运行时可用。

然后,您可以使用类似以下内容的东西加载文件:

string path = System.Io.Path.Combine(Application.StartupPath, @"\service\AppValues.xml");
XDocument doc = XDocument.Load(path);

当我尝试使用Application.StartupPath时,StartupPath会出现编译错误 - 它似乎不是Application的参数。我应该使用什么才能使它正常工作? - Tobias Roland
@T.Roland,Application.StartupPath是一个属性,用于确定应用程序所在的位置,从而确定相对路径。您可以尝试使用AppDomain.CurrentDomain.BaseDirectory或者在https://dev59.com/3G025IYBdhLWcg3wX070中提供的任何建议作为替代方案。 - Kami

0

检查一下这个

XDocument document = XDocument.Load(@"..\service\AppValues.xml");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接