Saving file in C# - 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:

Related

How to remove namespaces from XSD based C# object?

I have a class, created from Agresso's XSD using xsd.exe, which I successfully use to generate my XML file. I define an object ABWInvoice oInvoiceAgresso = new ABWInvoice() { }; , populate with relevant data and then save as an XML file, using the following method.
public static void SaveXml<ObjectType>(ObjectType o, string fileName)
{
using (var sw = new StreamWriter(myDecodePath(fileName)))
{
new XmlSerializer(typeof(ObjectType)).Serialize(sw, o);
}
}
The XML file has lots of namespaces, e.g.
<InvoiceDate xmlns="http://services.agresso.com/schema/ABWSchemaLib/2011/11/14">2018-02-05</InvoiceDate>
So far all well, but a customer now requires to remove the namespaces across the XML, i.e. to present only <InvoiceDate>2018-02-05</InvoiceDate>
There are lots of examples on the Net how to do it with an XML file, meaning I will have to continue saving my object as an XML file and then to reload it for processing.
I wonder if there is any better and I think also faster approach to do it directly on my oInvoiceAgresso object, rather than saving it first, please?
We use VS 2017.

ReadXml from a Resource - Explanation

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.

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:

Serialize to an XML document without overwriting previous data

I need to serialize to an XML document without overwriting the data that is currently in there. I have a method that does this and it will save to the xml file, but will delete whatever is currently in that file upon serializing. Below is the code.
public void SaveSubpart()
{
SOSDocument doc = new SOSDocument();
doc.ID = 1;
doc.Subpart = txtSubpart.Text;
doc.Title = txtTitle.Text;
doc.Applicability = txtApplicability.Text;
doc.Training = txtTraining.Text;
doc.URL = txtUrl.Text;
StreamWriter writer = new StreamWriter(Server.MapPath("~/App_Data/Contents.xml"));
System.Xml.Serialization.XmlSerializer serializer;
try
{
serializer = new System.Xml.Serialization.XmlSerializer(doc.GetType());
serializer.Serialize(writer, doc);
}
catch (Exception ex)
{
//e-mail admin - serialization failed
}
finally
{ writer.Close(); }
}
The contract for the StreamWriter constructor taking only a filename says that if the named file exists, it is overwritten. So this has nothing to do with serializing to XML, per se. You would get the same result if you wrote to the stream through some other means.
The way to do what you are looking for is to read the old XML file into memory, make whatever changes are necessary, and then serialize and write the result to disk.
And even if it was possible to transparently modify an on-disk XML file, that's almost certainly what would happen under the hood because it's the only way to really do it. Yes, you probably could fiddle around with seeking and writing directly on disk, but what if something caused the file to change on disk while you were doing that? If you do the read/modify/write sequence, then you lose out on the changes that were made after you read the file into memory; but if you modify the file directly on disk by seeking and writing, you would be almost guaranteed to end up with the file in an inconsistent state.
And of course, you could only do it if you could fit whatever changes you wanted to make into the bytes that were already on disk...
If concurrency is a problem, either use file locking or use a proper database with transactional support.
try this:
StreamWriter writer = new StreamWriter(Server.MapPath("~/App_Data/Contents.xml"),true);
this determines to append the data to the file.
true=append,
false = overwrite
more info http://msdn.microsoft.com/en-us/library/36b035cb.aspx
So what you want to implement is to serialize an object without overwriting it to an existing file.
Thus
XmlSerializer s = new XmlSerializer(doc.GetType());
TextWriter w = new StringWriter();
s.Serialize(w, doc);
var yourXMLstring = w.ToString();
Then you can process this xml string and append it to existing xml file if you want to.
XmlDocument xml = new XmlDocument();
xml.LoadXml(yourXMLstring );

How to set custom properties in the currently active Word document via OpenXML

So far I've been able to set custom properties to a Word doc by using VSTO and by adding a package stream to the active document as it follows
public static void SetCustomProperty(Microsoft.Office.Interop.Word.Document doc, string propertyName, object propertyValue)
{
using (MemoryStream stream = new MemoryStream())
using ((WordprocessingDocument wordDoc = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document, true))
{
SetProperty(wordDoc, propertyName, propertyValue);
// Flush the contents of the package.
wordDoc.Package.Flush();
// Convert back to flat OPC by using this in-memory package.
XDocument xDoc = OpcHelper.OpcToFlatOpc(wordDoc.Package);
// Return the xml string.
string openxml = xDoc.ToString();
// Add to Word doc
doc.CustomXMLParts.Add(openxml);
}
}
The SetProperty method works as explained here and the OpcHelper can be found here and is explained here.
The problem is that my custom property is inserted in a xml file (e.g. item1.xml) that is located in the folder document.zip\customXml of the OpenXML file format. Later on when I want to read my custom property I use the WordProcessingDocument.CustomFilePropertiesPart which is empty. In fact I found that CustomFilePropertiesPart references the document.zip\docProps\custom.xml file.
So instead of using doc.CustomXMLParts.Add(openxml); what should I use to populate the right xml file, i.e. document.zip\docProps\custom.xml?
EDIT
I tried already the solution proposed by Mishra without success, i.e custom properties were not always saved. However since he posted this solution I tried again and I found here that you firstly need to mark the document as unsaved:
doc.CustomDocumentProperties.Add("MyProp", False, MsoDocProperties.msoPropertyTypeNumber, 123);
doc.Saved = false;
doc.Save();
you cant set custome properties using CustomXMLParts collection. If you have document open better keep it simple and use CustomDocumentProperties collection, its quite fast and easy. I would use open XML in open doc only if the data to insert is vary large.

Categories

Resources