ReadXml from a Resource - Explanation - c#

I've been working on a project (C#) and part of it was filling a data grid with an embedded xml file.
Although I've now found a way to make this work, i am still confused as to to theory behind it. And I'd like to stop and make sure i fully understand it before i continue with this project.
The code that i have working currently is;
XmlDataDocument myXML = new XmlDataDocument();
StringReader mytempXML = (new StringReader(BasicTest.Properties.Resources.myxml));
myXML.DataSet.ReadXml(mytempXML);
What is confusing to me is that before this solution, I was trying the below;
myXML.DataSet.ReadXml(BasicTest.Properties.Resources.myxml);
and it wasn't working. However using the full file path (like below) was working.
myXML.DataSet.ReadXml("C:/..etc../myxml.xml");
The Question I have is: why is a StringReader required for the ReadXml method if you're reading from a resource, but using a full file path works without?
If anyone could provide an explanation, that would be great.
Thanks.

This is because the ReadXml method takes a string. That string must be the name of a file. It cannot be XML. If you pass it a string that is XML, it will think that is the name of the file! It doesn't have the smarts to look at the string and ask "Is this string XML, or is it a file name?" and figure that out.
// Summary:
// Reads XML schema and data into the System.Data.DataSet using the specified
// file.
//
// Parameters:
// fileName:
// The filename (including the path) from which to read.
public XmlReadMode ReadXml(string fileName);
By wrapping the XML in a stringreader or a stream or something, you are calling a different overload, that expects XML instead of a file name.

Related

Saving file in C#

I'm new to programming in C#. I want to create and download an xml file. I found this artical on creating the xml. I followed it and it works perfect. But I can't figure out how to save the file to my computer. I think it has to be inplemented someware here:
public static void Main()
{
// Read and write purchase orders.
Test t = new Test();
t.CreatePO("po.xml");
//I think here the file is ready to dowload
t.ReadPO("po.xml");
}
As for the t.CreatePO("po.xml"); function I have exactly whats in the artical.
From the artical I took the last example.
The 'file' is created by a StreamWriter. Then it converts an object to a XML by using Serialize.
Any step in the right direction will help!
For your question, you want to save the file to your computer.
You could try the following code to get it.
// Creates an instance of the XmlSerializer class;
// specifies the type of object to serialize.
XmlSerializer serializer =
new XmlSerializer(typeof(PurchaseOrder));
//We can use absolute paths to store it anywhere on the computer
string xmlPath = #"D:\Task\";
TextWriter writer = new StreamWriter(Path.Combine(xmlPath,filename));
PurchaseOrder po = new PurchaseOrder();
Result:

Insert Object data to local xml file

I found this great tutorial for loading XML using XLINQ (LINQ to XML).
http://www.codearsenal.net/2012/07/c-sharp-load-xml-using-xlinq.html
It helped me a lot and I got the job done with it.
The only change I made was where he had this line:
from e in XDocument.Load(#"..\..\Employees.xml").Root.Elements("employee")
I write it like this:
from el in XDocument.Load("XML_Files/Employees.xml").Root.Elements("employee")
I had to change the path like this to access a local xml file found right inside my Visual Studio project.
But now I need to save the data back to the file in my project solution. Again, my xml file is located inside my C# project. It's not on the desktop or anything, it is a file added to the project solution.
I can't seem to find any good resources for how to do this task. Does anyone know a good tutorial, or code, a reference to start?
I am inserting a list of objects into the xml files. The objects have basic data type properties, except for one of the object properties, which is a List of doubles.
Can anyone advise a good tutorial or link? Or even a generic code sample?
I'd like to keep this function as basic as possible.
Please help.
------------------ UPDATE ------------------
I actually got this kind of working now. The below code does what I need EXCEPT that it won't write the data to my local file in the Visual Studio project. It will gladly write the data to a test file I created on my desktop, however.
Does anyone know why this is??
//create the serialiser to create the xml
XmlSerializer serialiser = new XmlSerializer(typeof(List<Student>));
// Create the TextWriter for the serialiser to use
TextWriter Filestream = new StreamWriter(#"C:\\Users\\MyName\\Desktop\\output.xml");
//write to the file
serialiser.Serialize(Filestream, employees);
// Close the file
Filestream.Close();
-------- UPDATE ---------
Okay, figured it out.
This code works:
public void WriteXML()
{
//create the serialiser to create the xml
XmlSerializer serialiser = new XmlSerializer(typeof(List<Student>));
// Create the TextWriter for the serialiser to use
TextWriter Filestream = new StreamWriter(#"XML_Files\Employees.xml");
//write to the file
serialiser.Serialize(Filestream, employees);
// Close the file
Filestream.Close();
}
The data is inserted to the xml file, but it does not show in Visual Studio. But when I checked here:
C:\Users\Me\Desktop\MyProject\MyProject\bin\Debug\XML_Files
The file is overwritten.
Also, when I reload the data from the application again, the new entries come up.
The problem is in line:
TextWriter Filestream = new StreamWriter(#"C:\\Users\\MyName\\Desktop\\output.xml");
Change it to one of following:
TextWriter Filestream = new StreamWriter("C:\\Users\\MyName\\Desktop\\output.xml");
TextWriter Filestream = new StreamWriter(#"C:\Users\MyName\Desktop\output.xml");
Simply remove the "#", OR use single slashes:

Validate XDocument against a particular schema

I have an XDocument file that I have loaded. (confirmed the working). I need to validate this document. To do so I have an XSD file that I attached to the project as a embedded resource. I load
the xsd with these line of code:
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream("Project.Models.Ci.def.xsd");
How can I now validate the XML against this XSD? I only need to know if the document is valid or not, so nothing fancy.
There is a Validate extension method that might meet your needs. Take a look at this documentation on MSDN - it has sample code as well:
Extensions.Validate Method (XDocument, XmlSchemaSet, ValidationEventHandler, Boolean)

XML header missing after converting an XML file into a Binary Format File

I have a problem. I have an XML spreadsheet file that I'm trying to send via email. So I converted into a binary file and attached it to an email. The problem is when I'm trying to open it (on Excel), it's not showing the data that I saved. When I opened it like an XML file I realized that it didn't saved the XML header:
The way it should be:
<?xml version="1.0" encoding="utf-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
...
<Styles>
...
</Styles>
<Worksheet>
...
</Worksheet></Workbook>
after converting:
<Worksheet>
...
</Worksheet>
I've tried to use an xmldocument but i wasn't working, I also tried using a string, still not working. This is how I convert the XML to binary:
UTF8Encoding encoding = new UTF8Encoding();
binaryFile = encoding.GetBytes(xmlFile);
How can I fix this problem?
Thanks.
I think we need more information on how you're converting the XML file.
From your description it sounds like you've saved an Excel Spreadsheet to XML and for whatever reason you cannot just attach this text document to an email. My guess is you're using a method to attach the XML file that requires a byte array and can't just be provided a file location. If you could provide more information on this, it would help us figure out where things are going wrong for you.
The part I'm really stuck on is:
I've tried to use an xmldocument but i wasn't working, I also tried
using a string, still not working.
How did you try string? Did you read the file from disk using FileStream? If so, you should have been able to retrieve the full contents of the file.
Were you using XmlDocument the whole time and trying XmlDocument.OuterXml? This probably won't give you the control headers since they're not part of the XML body inside the root node.
So really there are two things I would have tried. First, if I had an XML file on disk and needed to attach it to an email through code and my only option was to provide a byte array, I'd do something like:
using (FileStream fs = new FileStream("", FileMode.Open, FileAccess.Read))
{
byte[] binaryFile = new byte[fs.Length];
fs.Read(binaryFile, 0, buff.LongLength);
//Copy the byte array to your email object.
}
Now if this isn't what you're doing, you'll need to provide a lot more detail on what you are starting with (file on disk?), what you need to do (send automated email?), what constraints you have and any other information that would limit potential solutions.
I've found my mistake: I didn't serialized the XML file so that's why after the conversion it just shows the data without the XML header. so there's 2 ways to resolve this problem:
first, we can concatenate the header with the data string, or we can use the serialize function. This is where I've found how to do it.

Invalid Assembly XML File

I am trying to read the XML Documentation file (C#) using this ocde -
Type classType = typeof(Point);
string documentationFileLocation = classType.Assembly.CodeBase;
if ( !string.IsNullOrEmpty(documentationFileLocation) && documentationFileLocation.StartsWith("file:///") )
{
documentationFileLocation = documentationFileLocation.Replace(".exe",".xml");
documentationFileLocation = documentationFileLocation.Replace("file:///","");
if(File.Exists(documentationFileLocation))
{
XElement document = XElement.Load(documentationFileLocation);
// Some Code Logic Here using LINQ
}
else
{
Console.WriteLine("Please Go to Project Properties->Build and check 'XML Documentation file'");
I have a LINQ Query after XElement document = XElement.Load(sr) which dosen`t work,
So I put a breakpoint in the LINQ Query and I am getting this error -
XmlException - Data at the root level is invalid. Line 1, position 1.
How I can fix it?
Edit:Changed the code a little - just deleted StreamReader
Well, it sounds like it simply isn't a valid XML file.
If you print out the result of sr.ReadToEnd() instead of calling XElement.Load, what does it look like? If you try to load the file into an XML editor, what happens?
Btw, it's better to use a using statement than calling Dispose explicitly: with your current code, the StreamReader isn't disposed if Load throws an exception.
Finally, is there any reason you're not just using XElement.Load(documentationFileLocation)?
Have you tried XDocument.Load() instead of using XElement? If the file begins with an XML declaration <?xml ..., you might get this error when trying to load an element from it.
Edit: the file you pasted on pastebin has no encoding specified. Can you try to open this file in notepad and re-save it as ANSI, the see if it loads? Just to make sure that we don't have an encoding or BOM problem.

Categories

Resources