64

How can I read from an embedded XML file - an XML file that is part of a c# project? I've added a XML file to my project and I want to read from it. I want the XML file to compile with the project because I don't want that it will be a resource which the user can see.

Any idea?

Pila
  • 679
  • 1
  • 5
  • 4

6 Answers6

108
  1. Make sure the XML file is part of your .csproj project. (If you can see it in the solution explorer, you're good.)

  2. Set the "Build Action" property for the XML file to "Embedded Resource".

  3. Use the following code to retrieve the file contents at runtime:

    public string GetResourceTextFile(string filename)
    {
        string result = string.Empty;
    
        using (Stream stream = this.GetType().Assembly.
                   GetManifestResourceStream("assembly.folder."+filename))
        {
            using (StreamReader sr = new StreamReader(stream))
            {
                result = sr.ReadToEnd();
            }
        }
        return result;
    }
    

Whenever you want to read the file contents, just use

string fileContents = GetResourceTextFile("myXmlDoc.xml");

Note that "assembly.folder" should be replaced with the project name and folder containing the resource file.

Update

Actually, assembly.folder should be replaced by the namespace in which a class created in the same folder as the XML file would have by default. This is typically defaultNamespace.folder0.folder1.folder2......

3Dave
  • 28,657
  • 18
  • 88
  • 151
  • 4
    The "Note" at the end of your answer appears to be incorrect. See this answer (http://stackoverflow.com/a/3314213/940783) which states you should enter the Default Namespace of your project, not just the project name. Just using the assembly name of the project was not working for me. – Jason Parker Sep 11 '13 at 16:31
  • @ClearCloud8 good call. The default namespace is automatically set to the project name, but that isn't a requirement and thus shouldn't be assumed. – 3Dave Sep 12 '13 at 22:57
  • 11
    If you need to list all the resources that are loaded, just look at `GetType().Assembly.GetManifestResourceNames()` – ogrim Feb 23 '15 at 08:23
  • 1
    @ogrim your comment is almost a solution. Great! – Daniele D. Oct 09 '15 at 16:40
31

You can also add the XML file as a Resource and then address its contents with Resources.YourXMLFilesResourceName (as a string, i.e. using a StringReader).

sunside
  • 8,069
  • 9
  • 51
  • 74
  • 3
    I am sorry but where is 'Resources' coming from? – dragonfly02 Aug 12 '15 at 16:04
  • I implicitly assumed Visual Studio here; that class should be autogenerated as soon as you mark a file as embedded resource. – sunside Aug 12 '15 at 16:19
  • @sunside thanks for the reply. It didn't generate Resources class in my case; is it because I am embedding the xml file to a Test class? I don't see why this should matter though. – dragonfly02 Aug 13 '15 at 08:45
  • Visual studio doesn't auto create a .cs wrapper for me either. There's no option to run a custom tool either. It may be specific to the type of assembly for the project – Jay Jan 25 '17 at 17:26
15

Set the Build Action to Embedded Resource, then write the following:

using (Stream stream = typeof(MyClass).Assembly.GetManifestResourceStream("MyNameSpace.Something.xml")) {
    //Read the stream
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
12

You can use Reflector (free from http://www.red-gate.com/products/reflector/) to find the path to the embedded XML file.

Then, it's just a matter of

Assembly a = typeof(Assembly.Namespace.Class).Assembly;

Stream s = a.GetManifestResourceStream("Assembly.Namespace.Path.To.File.xml");
XmlDocument mappingFile = new XmlDocument();
mappingFile.Load(s);
s.Close();
3Dave
  • 28,657
  • 18
  • 88
  • 151
Jamie
  • 2,948
  • 4
  • 19
  • 26
4
  1. Add the file to the project.
  2. Set the "Build Action" property to "Embedded Resource".
  3. Access it this way:

    GetType().Module.Assembly.GetManifestResourceStream("namespace.folder.file.ext")
    

Notice that the resource name string is the name of the file, including extension, preceded by the default namespace of the project. If the resource is inside a folder, you also have to include it in the string.

(from http://www.dotnet247.com/247reference/msgs/1/5704.aspx, but I used it pesonally)

bluish
  • 26,356
  • 27
  • 122
  • 180
Grzenio
  • 35,875
  • 47
  • 158
  • 240
1

@3Dave really helped (up vote given), however my resource helper was in a different assembly so I did the below

public string GetResourceFileText(string filename, string assemblyName)
    {
        string result = string.Empty;

        using (Stream stream = 
            System.Reflection.Assembly.Load(assemblyName).GetManifestResourceStream($"{assemblyName}.{filename}"))
        {
            using (StreamReader sr = new StreamReader(stream))
            {
                result = sr.ReadToEnd();
            }
        }
        return result;
    }

Called by

GetResourceFileText("YourFileNameHere.ext", Assembly.GetExecutingAssembly().GetName().Name);
Toby Simmerling
  • 2,228
  • 1
  • 11
  • 6