I've been trying to modify and save an xml dynamically. i've tried to find some answers but i didnt manage to.
i Succeeded to modify and change the xml data, but i encounter a problem with saving.
here is the code:
var resourceStreamInfo = Application.GetResourceStream(uri);
using (var stream = resourceStreamInfo.Stream)
{
doc = XDocument.Load(stream);
var Currencies = doc.Descendants("Currency");
XElement root = Currencies.Where(b => b.Element("ID").Value.IndexOf(CurrencyID, StringComparison.CurrentCultureIgnoreCase) >= 0).First();
root.SetElementValue("Rate", rate);
doc.Save(stream);
}
I understood that my stream is readonly, but what should I do?
From Application.GetResourceStreamI guess your are reading a file from your project bundle. You cannot modify it. You need to save the modified file to isolated storage
Related
I'm trying to edit xml file.
but document.Save() method has to use another file name.
Is there any way to use same file? or other method. Thank you!
string path = "test.xml";
using (FileStream xmlFile = File.OpenRead(path))
{
XDocument document = XDocument.Load(xmlFile);
var setupEl = document.Root;
var groupEl = setupEl.Elements().ElementAt(0);
var valueEl = groupEl.Elements().ElementAt(1);
valueEl.Value = "Test2";
document.Save("test-result.xml");
// document.Save("test.xml"); I want to use this line.
}
I receive the error:
The process cannot access the file '[...]\test.xml' because it is being used by another process.
The problem is that you are trying to write to the file while you still have it open. However, you have no need to have it open once you've loaded the XML file. Simply scoping your code more granularly will solve the issue:
string path = "test.xml";
XDocument document;
using (FileStream xmlFile = File.OpenRead(path))
{
document = XDocument.Load(xmlFile);
}
// the rest of your code
Normally I use SQL Server or Oracle for storage, so serializing to XML is a little new for me. I've had trouble locating answers that mirror what I'm doing enough for me to grasp what I've done wrong.
I have object MyObject and it has multiple properties. it is serializable. I need to store an IEnumerable<MyObject> to an xml file. This file is overwritten by a new list when saving, and when read needs to read directly back to an IEnumerable<MyObject> again.
I've managed to suppress the XML declaration and everything just fine on writes past the first, but I'm stuck on how to store this in a way I can read it back. Existing code (partially from searching around on here):
foreach (var i in items)
{
bool append = File.Exists(fileName);
using (var file = new StreamWriter(fileName,append))
{
///don't add XML declarative headers if the file already exists.
if (append == true)
{
///check to see if the
var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
using (var writer = XmlWriter.Create(file, settings))
{
xml.Serialize(writer, i, emptyNamespaces);
}
}
else
{
xml.Serialize(file, i);
//append = true;
}
}
}
Obviously, I'm looping through the list, with only the first item having the XML header information. The problem is, I get multiple root nodes this way. if I create a new root node manually, I can't seem to serialize back to MyObject> because it doesn't match a property or class. What approach should I use to be able to serialize and deserialize this list of objects?
I have been fiddling with this problem for the past hour so I thought you guys may be able to help on a Friday afternoon!
Problem
I am trying to edit an XML file in localstorage but can't figure out how to edit the existing file and re-save the file. The edit I have made it to remove a certain node from the XML.
Code
Here is the method that does all the work.
This first code snippet was already in the code and basically creates the XML file and saves it to localstorage.:
protected byte[] CreateFileData(PortableBusinessObjects.Location location, string geoObjectFilename)
{
byte[] fileData = null;
var xmlFile = System.IO.Path.GetFileNameWithoutExtension(geoObjectFilename) + ".xml";
var zipFile = System.IO.Path.GetFileNameWithoutExtension(geoObjectFilename) + ".zip";
using (IsolatedStorageFileStream fileStream = localStorage.CreateFile(xmlFile))
{
XmlWriter writer = XmlWriter.Create(fileStream);
if (location.GetType() == typeof(PortableBusinessObjects.Shape))
_xmlShapeSerializer.Serialize(writer, location);
else if (location.GetType() == typeof(PortableBusinessObjects.Point))
_xmlPointSerializer.Serialize(writer, location);
fileStream.Flush();
fileStream.Close();
}
}
This is my attempt at overwriting the saved file (Doesn't work):
using (IsolatedStorageFileStream doc = localStorage.OpenFile(xmlFile, FileMode.Open))
{
System.Xml.Linq.XDocument test = System.Xml.Linq.XDocument.Load(doc);
test.Descendants("Time").Remove();
XmlWriter writer = XmlWriter.Create(doc);
doc.Flush();
doc.Close();
}
Question
Where do I place my code that removes the "Time" nodes and saves the file?
Your saving code doesn't do any saving - you just create an XmlWriter and do nothing with it.
There are various methods built into XDocument than can help you here. While you could pass your XmlWriter to it, you can actually save directly to the stream:
test.Save(doc);
Note you will need to move to the beginning of the stream before writing to it - loading your XML will have read to the end:
doc.Position = 0;
You should use the IsolatedStorageFileStream together with the StreamWriter.
See How to: Read and Write to Files in Isolated Storage
With XDocument you then have to Save() the new contents to the stream.
I want to read xml on runtime, without save it on a path
After my searching i find that, In console application i need to use Console.Out for displaying result
xmlSerializer.Serialize(Console.Out, patient);
In Windows / Web Application we need to set path like
StreamWriter streamWriter = new StreamWriter(#"C:\test.xml");
but i need to read xml with out save it, i am using Webserive where i need to read it and take a decision that either it is valid or not
I hope i define it clearly..
Use the XmlDocument object.
There are several ways to load the XML, you can use the XmlDocument.Load() and specify your URL in there or use XmlDocument.LoadXml() to load the XML from a string.
You could use the XmlDocument.LoadXml class to read the received xml. There is no need to save it to disk.
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(receivedXMLStr);
//valid xml
}
catch (XmlException xe)
{
//invalid xml
}
Use Linq2Xml..
XElement doc;
try
{
doc=XElement.Load(yourStream);
}
catch
{
//invalid XML
}
foreach(XElement node in doc.Descendants())
{
node.Value;//value of this node
nodes.Attributes();//all the attributes of this node
}
Thanks all of you for your reply, i want to laod my XML without save it on a local Path, because saving creating many XML.
Finally i find the solutions for load the XML from class on a Memory stream, I thinn this solution is very easy and optimize
XmlDocument doc = new XmlDocument();
System.Xml.Serialization.XmlSerializer serializer2 = new System.Xml.Serialization.XmlSerializer(Patients.GetType());
System.IO.MemoryStream stream = new System.IO.MemoryStream();
serializer2.Serialize(stream, Patients);
stream.Position = 0;
doc.Load(stream);
You need to use the Deserialize option to read the xml. Follow the below steps to achieve it,
Create a target class. It structure should represent the xml output.
After creating the class, use the below code to load your xml into the target object
TargetType result = null;
XmlSerializer worker = new XmlSerializer(typeof(TargetType));
result = worker.Deserialize("<xml>.....</xml>");
Now the xml is loaded into the object 'result' and use it.
In an ASP.NET MVC I have a database table. I want to have a button on some view page, if some user clicks that button I my application will generate XML file containing all rows in the database. Then the file containing XML should be sent to the client so that the user will see a download pop-up window.
Similarly I want to allow user to upload an XML file whose content will be added to the database.
What's the simplest way to let the user upload and download file ?
Thanks for all the answers
EDIT:
This is my approach:
public FileContentResult Download() {
if(model.Series.Count() < 1) {
byte[] content = new byte[0];
return new FileContentResult(content, "Series");
}
XmlSerializer serializer = new XmlSerializer(model.Series.FirstOrDefault().GetType());
MemoryStream xmlStream = new MemoryStream();
foreach (Series s in model.Series) {
serializer.Serialize(xmlStream, s);
}
byte[] content2 = new byte[xmlStream.Length];
xmlStream.Position = 0;
xmlStream.Read(content2, 0, (int) xmlStream.Length);
return File(content2, "Series");
}
Where model is DataContext. Howewer this does not work. When I try to download the data I get this error:
XML Parsing Error: junk after document element
Location: http://localhost:1399/Xml/Download
Line Number 7, Column 10:</Series><?xml version="1.0"?>
---------^
for download part, you could use FileStreamResult
This page has examples for upload and download; check it out.
An XML document can only have one top level element. After the end of the element, you cannot have anything else. It looks like after the "</Series>" element you have "<?xml version="1.0>", which is invalid.