Writing to XML in a Pocket PC - c#

I have a list of songs which I want to output to an external XML file using a smart device (pocket pc).
String path = GetAppDir();
string filePath = path + #"\output\songs.xml";
XmlWriter xmlOut = XmlWriter.Create(filePath, settings);
xmlOut.WriteStartDocument();
xmlOut.WriteStartElement("Songs");
foreach (Song songTmp in finalbasket)
{
xmlOut.WriteStartElement("Songs");
xmlOut.WriteAttributeString("Name", songTmp.SongName);
xmlOut.WriteElementString("Artist", songTmp.SongArtist);
xmlOut.WriteElementString("Price", Convert.ToString(songTmp.SongPrice));
xmlOut.WriteEndElement();
}
xmlOut.WriteEndElement();
xmlOut.Close();
The application seems to write the xml document but it always comes up empty. There are indeed items in the 'finalbasket' list. Any ideas what I am doing wrong?

I think you need an
xmlOut.WriteEndDocument();
right before the xmlOut.Close(). Also, I'm not sure if this is part of your problem, but this line:
xmlOut.WriteStartElement("Songs");
should probably be this:
xmlOut.WriteStartElement("Song");

Related

Unable to save changes to XML document stored in Sharepoint 2010 Document Library

I am working on a project that requires all SQL connection and query information to be stored in XML files. To make my project configurable, I am trying to create a means to let the user configure his sql connection string information (datasource, catalog, username and password) via a series of text boxes. This input will then be saved to the appropriate node within the SQL document.
I can get the current information from the XML file, and display that information within text boxes for the user's review and correction, but I'm encountering an error when it comes time to save the changes.
Here is the code I'm using to update and save the xml document.
protected void submitBtn_Click(object sender, EventArgs e)
{
SPFile file = methods.web.GetFile("MyXMLFile.xml");
myDoc = new XmlDocument();
byte[] bites = file.OpenBinary();
Stream strm1 = new MemoryStream(bites);
myDoc.Load(strm1);
XmlNode node;
node = myDoc.DocumentElement;
foreach (XmlNode node1 in node.ChildNodes)
{
foreach (XmlNode node2 in node1.ChildNodes)
{
if (node2.Name == "name1")
{
if (node2.InnerText != box1.Text)
{
}
}
if (node2.Name == "name2")
{
if (node2.InnerText != box2.Text)
{
}
}
if (node2.Name == "name3")
{
if (node2.InnerText != box3.Text)
{
node2.InnerText = box3.Text;
}
}
if (node2.Name == "name4")
{
if (node2.InnerText != box4.Text)
{
}
}
}
}
myDoc.Save(strm1);
}
Most of the conditionals are empty at this point because I'm still testing.
The code works great until the last line, as I said. At that point, I get the error "Memory Stream is not expandable." I understand that using a memory stream to update a stored file is incorrect, but I can't figure out the right way to do this.
I've tried to implement the solution given in the similar question at Memory stream is not expandable but that situation is different from mine and so the implementation makes no sense to me. Any clarification would be greatly appreciated.
Using the MemoryStream constructor that takes a byte array as an argument creates a non-resizable instance of a MemoryStream. Since you are making changes to the file (and therefore the underlying bytes), you need a resizable MemoryStream. This can be accomplished by using the parameterless constructor of the MemoryStream class and writing the byte array into the MemoryStream.
Try this:
SPFile file = methods.web.GetFile("MyXMLFile.xml");
myDoc = new XmlDocument();
byte[] bites = file.OpenBinary();
using(MemoryStream strm1 = new MemoryStream()){
strm1.Write(bites, 0, (int)bites.Length);
strm1.Position = 0;
myDoc.Load(strm1);
// all of your edits to the file here
strm1.Position = 0;
// save the file back to disk
using(var fs = new FileStream("FILEPATH",FileMode.Create,FileAccess.ReadWrite)){
myDoc.Save(fs);
}
}
To get the FILEPATH for a Sharepoint file, it'd be something along these lines (I don't have a Sharepoint development environment set up right now):
SPFile file = methods.web.GetFile("MyXMLFile.xml")
var filepath = file.ParentFolder.ServerRelativeUrl + "\\" + file.Name;
Or it might be easier to just use the SaveBinary method of the SPFile class like this:
// same code from above
// all of your edits to the file here
strm1.Position = 0;
// don't use a FileStream, just SaveBinary
file.SaveBinary(strm1);
I didn't test this code, but I've used it in Sharepoint solutions to modify XML (mainly OpenXML) documents in Sharepoint lists. Read this blogpost for more information
You could look into using the XDocument class instead of XmlDocument class.
http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx
I prefer it because of the simplicity and it eliminates having to use Memory Stream.
Edit: You can append to the file like this:
XDocument doc = XDocument.Load('filePath');
doc.Root.Add(
new XElement("An Element Name",
new XAttribute("An Attribute", "Some Value"),
new XElement("Nested Element", "Inner Text"))
);
doc.Save(filePath);
Or you can search for an element and update like this:
doc.Root.Elements("The element").First(m =>
m.Attribute("An Attribute").Value == "Some value to match").SetElementValue(
"The element to change", "Value to set element to");
doc.Save('filePath');

Can't load file from path

I have an problem loading an xml from a path, because on my pc(and others) part of the path is mapped:
This is the path i have from the database:
\serverName\files\System\Appldata\Application\3_5\TEST\Program\Version.xml
But on my computer the path looks like this:
Y:\Application\3_5\TEST\Program
This is the code:
var path = new DirectoryInfo(x.LocationName+#"\"+x.FolderName);
var doc = new XmlDocument();
//Loading the file
doc.Load(path.FullName + #"\Version.xml");
Are there any way around this problem?
Well, do not try to concatenate by yourself the path and the filename.
Use Path.Combine
doc.Load(Path.Combine(path.FullName, "Version.xml"));
This requires the using System.IO; at the beginning of your source file.
Of course you could use both the mapped version or the full sharename only if you have the permissions to you remote folder. Also, if your database keeps the full sharename be sure that it is stored with the two initial backslash
EDIT Seeing your edit now, again, do not manually build your paths (and check if the info are valid)
var path = new DirectoryInfo(Path.Combine(x.LocationName, x.FolderName));
if(!path.Exists)
{
MessageBox.Show("Invalid path retrieved:" + path.FullName);
return;
}
var doc = new XmlDocument();
doc.Load(Path.Combine(path.FullName,"Version.xml"));
You are accessing the file using network path. Please make sure that you are able to access the file from the file explorer on webserver.
Try this code:
var doc = new XmlDocument();
var finalPath = Path.Combine(x.LocationName, x.FolderName, "Version.xml");
//Loading the file
doc.Load(finalPath);

Visual studio cannot locate XML file

I'm attempting to develop a Windows 7 Phone and I am using an XML file that I need to parse and then perform a Linq query on.
The problem is this:
Whenever I try to access the file (it is stored locally) it brings back an error saying the file cannot be found as it's not part of the XAP package.
I have tried another solution where I use StreamReader But I am still getting a simular error:
Attempt to access the method failed System.IO.File.OpenText(System.String)
Here is the code that I am using:
using (StreamReader reader = File.OpenText("C:/Users/Desktop/Assign/obj/Debug/buildings.kml"))
{
var xdoc = XDocument.Load ("buildings.kml");
XNamespace kml = "http://www.opengis.net/kml/2.2";
var dict = xdoc.Descendants(kml + "Placemark")
.ToDictionary(d => d.Element(kml + "name").Value,
d => d.Element(kml + "id").Value);
foreach (var b in dict) {
Console.WriteLine ("Building Name -> " + b.Key + " Building ID -> " + b.Value);
}
}
The file is located in: > C:/Users/Desktop/Assign/obj/Debug/buildings.kml so I cannot see the problem. Outside of Visual Studio, I can read in the .xml file fine.
Hope someone can help
EDIT:
New code -
Dictionary<string, string> getBuildingNames()
{
Uri uri = new Uri(#"Data\mydata.kml", UriKind.Relative);
StreamResourceInfo sri = Application.GetResourceStream(uri);
StreamReader sr = new StreamReader(sri.Stream);
var xdoc = XDocument.Load(sr);
XNamespace kml = "http://www.opengis.net/kml/2.2";
var dict = xdoc.Descendants(kml + "Placemark")
.ToDictionary(d => d.Element(kml + "name").Value,
d => d.Element(kml + "id").Value);
return dict;
}
Error: - 'NullReferenceException was unhanded'
Assuming you really are trying to do this as part of a WP7 project (rather than some non-mobile project related to it, e.g. preprocessing) you shouldn't be using File.OpenText.
Options:
Include the XML in your XAP file, and read from that using Application.GetResourceStream (see this blog post for details)
Somehow get the XML into isolated storage, and use the isolated storage API
Embed the resource into your assembly, and use Assembly.GetManifestResourceStream.
Just a couple of some more tips to help you along:
1) Change the Build action property of the xml file to "Content". (Select the file and go to the properties window in Visual Studio)
2) If you only want to read from the file, then there is no need to have the file in IsolatedStorage. You can simply read it if you correctly set the Build Action property.
You can use XDocument to read the file.
XDocument xdoc = XDocument.Load(filepath);
where filepath is simply the relative path to the XML file, i.e. if you did not place it inside any folder in your project then it will be just the file name (assume it like being the root directory)

update / save a same xml in .Net c#

I m trying to edit a xml file. After update my value, i would like to save it in same original xml file. When i attend to save into this file, i have an error "could not save into this file because it still open". Need some idea | help.
Thanx :)
public void writeConfig(string withConfig, string param)
{
XmlTextReader reader = new XmlTextReader(pathFile);
XElement xmlFile = XElement.Load(reader);
reader.Close();
var query = from c in xmlFile.Elements("config").Attributes(withConfig) select c;
foreach (XAttribute config in query)
{
config.Value = param;
}
xmlFile.Save(pathFile);
}
It worked fine for me, even when I had the file open in TextPad.
Did you try looking into the current processes to see if any other program is holding that up? You can try using Process Explorer to look for such processes.

write the list of files in a folder to afile

I wrote a code to read all the files in a folder, then write them to a file. All the code complies and runs okay, but the filenames of the files are not displayed in the new file.
Code:
private void Form1_Load(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog(); // Show the dialog.
// create a list to insert the data into
//put all the files in the root directory into array
string[] array1 = Directory.GetFiles(#"C:\Users\a3708906\Documents\Filereader m 15062012", "*.csv");
// Display all files.
TextWriter tw1 = new StreamWriter("C:/Users/a3708906/Documents/Filereader m 15062012/Filereader m 15062012/listoffiles.txt");
List<string> filenames = new List<string>();
tw1.WriteLine("--- Files: ---");
foreach (string name in array1)
{
tw1.WriteLine(name);
}
tw1.Close();
}
I would be grateful for your assistance.
You took the trouble to ask the user the folder location, yet you don't retrieve that folder location. The code should be
string[] array1 = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.csv");
// Display all files.
TextWriter tw1 = new StreamWriter(folderBrowserDialog1.SelectedPath+"/listoffiles.txt");
If the file isn't created (ie its just not there, even if it's just blank) then you problem lies with the stream writer. If this is the case I would suggest changing the direction of slashes so that your path is
TextWriter tw1 = new StreamWriter("C:\\Users\\a370890\\Documents\\Filereader m 15062012\\Filereader m 15062012\\listoffiles.txt");
If the file is created but nothing is written have a look at the flush command.
tw1.Flush();
Set a breakpoint to verify that GetFiles is returning files.
(Consider renaming array1 to something more meaningful)
Set a breakpoint on tw1.WriteLine(name) and ensure it is being hit.
It should be pretty easy to see the problem. My guess is that you simply aren't getting any files returned from GetFiles, but the breakpoints will tell you for sure. If your output file is created but missing the files - this is most likely the case.
If your output file doesn't exist; take a closer look at your file writing code.
I would say that your "space" in your folderpath is messing things up. Try to escape the "whitespace" by following the explanations in the msdn
I think problem is with your file path or file writing capability.
You use folderbrowserdialog but do not use it to get selected file
name. Instead you give path manually. also your output path can have
problem.
Try this :
using(system.IO.StreamWriter tw1 =
new system.IO.StreamWriter(#"C:/Users/a3708906/Documents/Filereader m 15062012/Filereader m 15062012/listoffiles.txt")
{
foreach (string name in array1)
{
tw1.WriteLine(name);
}
}

Categories

Resources