Packagepart copy to file or to memory - c#

I want to extract a xlsx file to get the sheet1.xml file. Now I am struggling with the package and PackagePart. I think the most obvious way is to read that particular file and copy the content to the XmlDocument
This is what i have this far:
XmlDocument doc = new XmlDocument();
using (Package package = ZipPackage.Open(xlsFile, FileMode.Open, FileAccess.Read))
{
foreach (PackagePart part in package.GetParts())
{
var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/')));
var targetDir = target.Remove(target.LastIndexOf('\\'));
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
{
FileStream targetFile = File.OpenWrite(target);
byte[] bytes = new byte[source.Length];
source.Read(bytes, 0, (int)source.Length);
source.Close();
//source.CopyTo(targetFile);
//doc.Load(source.Write());
//targetFile.Close();
}
}
}
I am using .net 3,5 so I cannot use the Stream source.CopyTo methods.
I would like to copy the contents of the Sheet1.xml to the doc of the XmlDocument class..
Thanks!
Paul

You can use XmlDocument.Load overload which takes a Stream:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(part.GetStream(FileMode.Open, FileAccess.Read));
Once loaded, you then can use XmlDocument.Save:
xmlDoc.Save(target);

Related

How to add XML schema and XML element together in same file?

**
I want to add XML schema and XML element together in same file. Because this xml file we will need to generate through C# based on specific record. So, i am looking some code help how can i write together XMLSchema and XML element in same file and inside same element. Please check attachment.
<Survey>
**Here i want XML schema**
**Here i want XML element**
</Survey>
Working Code Example
SiteSurveyX siteSurveyX = new SiteSurveyX();
XmlTextReader reader = new XmlTextReader("c:\\temp\\TestSiteSchema.xsd");
//siteSurveyX.SurveySchema = XmlSchema.Read(reader, null);
XmlSchema myschema = XmlSchema.Read(reader, null);
string filePath = HelperFunctions.SurveyFilePath + routeName;
////Get all node record from DB
siteSurveyX.Survey = routeService.GetRouteDetailForXML(routeId, Convert.ToString(ddlRoute.Text), chkCurrentInterruption.Checked);
using (FileStream stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite))
{
lblStatus.Text = "Preparing file";
stream.Close();
stream.Dispose();
//Convert record in XML
XmlSerializer serializer = new XmlSerializer(typeof(SiteSurveyX));
using (StreamWriter writer = new StreamWriter(filePath, true))
{
serializer.Serialize(writer, siteSurveyX);
lblStatus.Text = "Ready";
}
}
It's done with this code.

Edit ZipArchive in memory .NET

I'm trying to edit a XmlDocument file contained in a Zip file:
var zip = new ZipArchive(myZipFileInMemoryStream, ZipArchiveMode.Update);
var entry = zip.GetEntry("filenameToEdit");
using (var st = entry.Open())
{
var xml = new XmlDocument();
xml.Load(st);
foreach (XmlElement el in xml.GetElementsByTagName("Relationship"))
{
if(el.HasAttribute("Target") && el.GetAttribute("Target").Contains(".dat")){
el.SetAttribute("Target", path);
}
}
xml.Save(st);
}
After executing this code the contained file is not changed. IF instead of xml.Save(st); I write the xml to disk, I got the edited one.
Why is the edited file not written to the zip? How do I fix it?
EDIT:
I updated the code:
var tmp = new MemoryStream();
using (var zip = new ZipArchive(template, ZipArchiveMode.Read, true))
{
var entry = zip.GetEntry("xml");
using (var st = entry.Open())
{
var xml = new XmlDocument();
xml.Load(st);
foreach (XmlElement el in xml.GetElementsByTagName("Relationship"))
{
if (el.HasAttribute("Target") && el.GetAttribute("Target").Contains(".dat"))
{
el.SetAttribute("Target", path);
}
}
xml.Save(tmp);
}
}
using (var zip = new ZipArchive(template, ZipArchiveMode.Update, true))
{
var entry = zip.GetEntry("xml");
using (var st = entry.Open())
{
tmp.Position = 0;
tmp.CopyTo(st);
}
}
In this way the zip file is edited, but it works only if the length of the streams is equal. If tmp is shorter the rest of the st is still in the file...
Hints?
I use this code to create a Zip InMemory (using the DotNetZip Library) :
MemoryStream saveStream = new MemoryStream();
ZipFile arrangeZipFile = new ZipFile();
arrangeZipFile.AddEntry("test.xml", "content...");
arrangeZipFile.Save(saveStream);
saveStream.Seek(0, SeekOrigin.Begin);
saveStream.Flush(); // might be useless, because it's in memory...
After that I have a valid Zip inside the MemoryStream. I'm not sure why I added the Flush() - I would guess this is redundant.
To edit an existing Zip you could read it in a MemoryStream and instead of creating "new ZipFile()" use "new ZipFile(byteArray...)".

Read xml data file into Windows.Data.Xml.Dom.XMLDocument

How can we read a xml data file into Windows.Data.Xml.Dom.XMlDocument?
The following code is possible only for System.Xml.XmlDocument.
XmlDocument myxml = XmlDocument.Load("abc.xml");
I read the xml file content to a string, and then use LoadXml():
string fileContent;
StorageFile tileTemplateFile =
await StorageFile.GetFileFromApplicationUriAsync(new Uri(#"<path to file>"));
using (StreamReader reader =
new StreamReader(await tileTemplateFile.OpenStreamForReadAsync()))
{
fileContent = await reader.ReadToEndAsync();
}
XmlDocument tileXml = new XmlDocument();
tileXml.LoadXml(fileContent);
I got most of the code from this answer.
You need to do the following.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(<string representation of your xml>);

how to save xmldocument to a stream

I've already written code to parse my xml file with an XmlReader so I don't want to rewrite it. I've now added encryption to the program. I have encrypt() and decrypt() functions which take an xml document and the encryption algorithm. I have a function that uses an xml reader to parse the file but now with the xml document I'm not sure how to create the xmlreader.
The question is how to save my xml document to a stream. I'm sure it's simple but I don't know anything about streams.
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(filep);
Decrypt(doc, key);
Stream tempStream = null;
doc.Save(tempStream); // <--- the problem is here I think
using (XmlReader reader = XmlReader.Create(tempStream))
{
while (reader.Read())
{ parsing code....... } }
You can try with MemoryStream class
XmlDocument xmlDoc = new XmlDocument( );
MemoryStream xmlStream = new MemoryStream( );
xmlDoc.Save( xmlStream );
xmlStream.Flush();//Adjust this if you want read your data
xmlStream.Position = 0;
//Define here your reading
Writing to a file:
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<FTPSessionOptionInfo><HostName>ftp.badboymedia.ca</HostName></FTPSessionOptionInfo>");
using (StreamWriter fs = new StreamWriter("test.xml"))
{
fs.Write(doc.InnerXml);
}
}
I realize this is an old question, but thought it worth adding a method from this nice little blog post. This edges out some less performant methods.
private static XDocument DocumentToXDocumentReader(XmlDocument doc)
{
return XDocument.Load(new XmlNodeReader(doc));
}
try this
XmlDocument document= new XmlDocument( );
string pathTmp = "d:\somepath";
using( FileStream fs = new FileStream( pathTmp, FileMode.CreateNew ))
{
document.Save(pathTmp);
fs.Flush();
}

I want to edit my xml file

Hi I am working on XML file, here I want to give rights to user to edit my xml file nodes to his own custom language.
I am enclosing my code, but it is not editting my xml file. Need assistance.
class Program
{
static void Main(string[] args)
{
//The Path to the xml file
string path = "D://Documents and Settings//Umaid//My Documents//Visual Studio 2008//Projects//EditXML//EditXML//testing.xml";
//Create FileStream fs
System.IO.FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Create new XmlDocument
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
//Load the contents of the filestream into the XmlDocument (xmldoc)
xmldoc.Load(fs);
//close the fs filestream
fs.Close();
//Change the contents of the attribute
xmldoc.DocumentElement.ChildNodes[0].Attributes[0].InnerText = "Umaid";
// Create the filestream for saving
FileStream WRITER = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
// Save the xmldocument
xmldoc.Save(WRITER);
//Close the writer filestream
WRITER.Close();
}
}
My XML file which I am going to edit, but couldn't.
<?xml version="1.0" encoding="utf-8" ?>
<rule id="city" scope="public">
<one-of>
<item>Boston</item>
</one-of>
</rule>
What do you really want to do with your XML?? Which attribute to you want to change??
One hint: you can load and save XmlDocument to a path directly - no need for the filestream .....
xmldoc.Load(#"D:\yourpath\file.xml");
xmldoc.Save(#"D:\yourpath\newfile.xml");
The problem is that your expression xmldoc.DocumentElement.ChildNodes[0] selects the <one-of> node which has no attributes.
You cannot change a non-existing attribute.
If you want to change the "id" attribute of <rule>, you need to do this on the DocumentElement:
xmldoc.DocumentElement.Attributes["id"].Value = "Umaid";
If you want to change the text inside the <item>, do this:
XmlNode itemNode = xmldoc.SelectSingleNode("/rule/one-of/item");
if(itemNode != null)
{
itemNode.InnerText = "Umaid";
}
Marc
class Program
{
static void Main(string[] args)
{
string path = "D:\\Documents and Settings\\Umaid\\My Documents\\Visual Studio 2008\\Projects\\EditXML\\EditXML\\testing.xml";
XmlDocument doc = new XmlDocument();
doc.Load(path);
var itemNode = doc.SelectSingleNode("rule/one-of/item");
if (itemNode != null)
{
itemNode.InnerText = "Umaid";
}
doc.Save(path);
}
}

Categories