I have an XSLT file that I want to load and use to transform an XML file. I've added the file to the same project as the code that uses it and put it in the "Resources" folder and set the Build Action to "Resource".
This is the code that tries to access the file:
XslCompiledTransform myXslTransform = new XslCompiledTransform();
myXslTransform.Load(#"[projectName];component/Resources/OrderManagement/OrderOverview.xslt");
... where [projectName] is the name of the project. However this doesn't seem to work. I've played around with different paths, but somehow I don't seem to get it right. I'm sure it's just a little thing, but none of the articles I have found on the internet (or here) have helped me.
Can anyone help?
A co-worker has helped me find a solution. We added the resource via the properties of the project, so that I can access its content easily and used the following code.
using (var reader = new StringReader(Resources.OrderOverview)) {
using (XmlReader xmlReader = XmlReader.Create(reader)) {
myXslTransform.Load(xmlReader);
myXslTransform.Transform(fileName, arguments, xmlTextWriter);
}
}
This is very similar to what outcoldman suggested with the subtle difference that the resource is accessed differently.
Change the build action from Resource to Embedded Resource, after this you can do something like
XslCompiledTransform myXslTransform = new XslCompiledTransform();
var assembly = typeof(SomeTypeFromAssemblyWithResource).Assembly;
using (var stream = assembly.GetManifestResourceStream("Resources.OrderManagement.OrderOverview.xslt"))
{
using (var xmlReader = XmlReader.Create(stream))
{
myXslTransform.Load(xmlReader );
}
}
Resource name in dll can be tricky so maybe you want first to know the resource name with Assembly.GetManifestResourceNames. Compiler generates name based on the folder and assembly.
Related
I have a file in my Xamarin Android project called "SaveData.xml". I can't save it in the assets folder because I need to write to it during runtime. I am trying to access it with my LoadXML() function:
XmlDocument doc = new XmlDocument();
XmlDocument saveData = new XmlDocument();
public void LoadXML()
{
saveData.Load("SaveData.xml");
//This bit works fine.
AssetManager assets = this.Assets;
using (StreamReader sr = new
StreamReader(assets.Open("Spices.xml")))
{
doc.Load(sr);
}
}
I've tried reading up on it but all the answers say to just save in assets folder. I can't do that because I need to write to this file and then read it again every time the app starts. I also tried putting it in the resources folder and changing the build action. Is the file path wrong? do I need to save it somewhere else? I'm stumped.
EDIT: Sorry for not being specific. "saveData.Load("SaveData.xml")" Is throwing a file not found exception and I want to know why.
Here is the xml file.
SaveData.xml
<?xml version="1.0" encoding="utf-8" ?>
<list>
<cupboard></cupboard>
<shoppingList></shoppingList>
</list>
Yes, if you need to write to the xml during runtime application, we can't put it into the assets folder as it's read-only.
Besides, when you execute saveData.Load("SaveData.xml"), you're not specifying a target directory, so it's defaulting to the root directory, then it will throw a file not found exception.
So you'll need to write the file to a location you have write access to.
The code below will specify a file in the user's home directory, which will be writeable:
using System.IO;
string backingFile_path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "SaveData.xml");
For more details, you can check: https://learn.microsoft.com/en-us/xamarin/android/platform/files/
Note:There is a sample included in this link which you can refer to.
The following code works fine in Windows, however, when using Xamarin and targeting iOS, GetManifestResourceStream() returns null.
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream("CommunicationModel.XmlSchemas.DeviceCommon.xsd");
I have set the file 'DeviceCommon.xsd' as an Embedded Resource. Not sure why it is not returning a valid stream.
Does anybody know why this is not working in iOS using Xamarin?
UPDATE:
Ok, so I followed the advice in the comments and set the file to Content.
I can now detect the file, but cannot open it:
if (File.Exists("DeviceCommon.xsd"))
{
try
{
myStream = new FileStream("DeviceCommon.xsd", FileMode.Open);
}
....
}
When I run the above code, the 'File.Exists()' call works, but when I attempt to open it, I get the following exception:
Access to the path "/private/var/mobile/Applications/8BD48D1F-F8E8-4A80-A446-F807C6728805/UpnpUI_iOS.app/DeviceCommon.xsd" is denied.
Anybody have some ideas how I can fix this???
Thanks,
Curtis
Ok, I finally got it to work. In my case, I was using the same files for a windows .dll and for a Xamarin.iOS.dll. I had named the .dll projects differently, though the namespaces were the same. Unfortunately, the microsoft documentation says that they use the namespace as part of the filename. That is no true.. They use the .dll name as part of the namespace. Just a slight difference, but makes all the difference.
So, to the point.. I set the file properties to: 'Embedded Resource' and 'Do not copy'. The resources I needed to process were all files with an .xsd extension, so I just looped through all resource names and used those that ended in .xsd. This way, no matter what operating system they were on, the name would be right because I retrieved it programmatically and didn't hard code it:
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resources = assembly.GetManifestResourceNames();
foreach (string resource in resources)
{
if(resource.EndsWith(".xsd"))
{
Stream stream = assembly.GetManifestResourceStream(resource);
if (stream != null)
{
XmlSchema schema = XmlSchema.Read(stream, null);
_schemas.Add(schema);
}
}
}
As for me what I had to do is prefix it properly. Instead of looking for "fooBar.baz", look for "The.Name.Of.The.Assembly.The.Folder.Inside.fooBar.baz".
I have an xml file, currently external to the C# code and it is loaded like this:
var xElem = XElement.Load("ProductTable.xml");
How do I "use" this file as an "embedded" element in my C# code instead of having it as an external file?
I know I am not clear enough with the words "use" and "embedded". What I want to do is to use it as some kind of variable such as
var myXML = /* content of the XML file here */;
just so that I don't have to use an external xml file. Thanks.
You have a resources file in your project. Just dragNdrop it there and you will be able to access it.
Another way is to add this file to project, then click properties, set compile method to emedded and then do smth like this
try
{
_assembly = Assembly.GetExecutingAssembly();
_imageStream = _assembly.GetManifestResourceStream("MyNamespace.MyImage.bmp");
_textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyXmlFile.xml"));
}
catch
{
MessageBox.Show("Error accessing resources!");
}
Add the XML file to your project. Set its build setting (in properties via Solution Explorer) to Embedded Resource. Then you can use something like...
var asm = Assembly.GetExecutingAssembly();
using (var sr = new StreamReader(asm.GetManifestResourceStream("YourNamespace.ProductTable.xml")))
{ /* ... */ }
You'll probably want to use the XmlReader or whatever they call it these days.
Derived from How to embed and access... from MSDN.
I have an XML file included as part of my Silverlight 4.0 project that I'd like to access at runtime. I have the file saved in a directory named Resources with the Build Action set to "Content" and the Copy to Output Directory set to "Do not copy". If I decompress the XAP file, I see the XML file in the location I expect it to be, but I'm not sure how to reference it from code. I currently have the following:
Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(#"/AssemblyName;component/Resources/MyFile.xml")
Unfortunately, stream is null after running the code above. In addition to the path mentioned above, I've tried "/Resources/MyFile.xml", "/MyFile.xml" and "MyFile.xml", but they all experience the same behavior.
What is the correct way to access an XML file embedded as a resource in a Silverlight application?
A resource with build action "Content" just gets embedded into the xap file, with the same relative directory structure as the application. It does not get embedded as a resource in the assembly.
When set to build action "Content", you should be able to just load the file using something like (or whatever suits your needs):
XElement.Load(<relative directory>/<file>)
The method you're using currently (using a resource stream) is for embedded resources (which have their build action set to "Resource"). And for those, although I haven't tried yet if your method works, usually you'll get the resources using
Application.GetResourceStream
I have used the code snip below to get access to drawables. Not sure it's completely relevant, but hoping this will give you a hint one way or another ...
Resources res = getResources();
spec = tabHost.newTabSpec("groups").setIndicator("Groups", res.getDrawable(R.drawable.ic_tab_groups)).setContent(intent);
As was mentioned by Willem van Rumpt, "content" resources are not usual resources (they aren't stored in assembly). I've checked out this article and could't found at all that you could reference resource, marked as "content" from other assembly.
So, you have two options:
Define XML as embedded resource
Define XML as resource
In first case stream request looks like:
var a = Assembly.Load("AssemblyName");
var s = a.GetManifestResourceStream(#"DefaultNamespace.Resources.XMLFile2.xml");
In second case:
var a = Assembly.Load("AssemblyName");
var rm = new ResourceManager("AssemblyName.g", a);
using (var set = rm.GetResourceSet(CultureInfo.CurrentCulture, true, true))
{
var ums = (UnmanagedMemoryStream)set.GetObject(#"Resources/XMLFile1.xml", true);
}
Hope this helps.
Is it possible to embed a custom binary file inside a C# class library and then at runtime read it with a binary reader?
I'm guessing it might be possible through resources.
Many thanks
You can do this by adding the file to the Resources through the project properties. Visual studio will then give you a handy class to access your file using the following code
byte[] theFile = myNamespace.Properties.Resources.theBinaryFile;
Where the resource name is theBinaryFile.
Yes it is easy:
Add the file to your project and set the "Build action" to "Embedded resource".
In your program do
foreach (string name in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
if (name.EndsWith("<name>", StringComparison.InvariantCultureIgnoreCase))
{
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
// ...
}
break;
}
}
Finding the right resource is a little bit complicating because there is stuff in front of the file name (namespaces etc. set a breakpoint to the if(...) to see the real resource name).