C# XMLdocument writing same thing over again - c#

In my application, lots of data is generated and then written in a XML file using XmlDocument.
The mechanics works fine, but when I call the function that serializes again and again to write data in a new XML, it copies what it wrote previously to the new XML plus the new data!
I don't understand, I'm calling XmlDocument doc = new XmlDocument() at the beggining of the function that serializes...
private static Boolean SaveParsedDataAsXML(ParsedData DataParsed, String Name)
{
try
{
XmlDocument doc = new XmlDocument();
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, "", "");
doc.AppendChild(xmlnode);
XmlElement generalVariables = doc.CreateElement("Variables");
generalVariables.AppendChild(SerializeElement(doc, "Path", DataParsed.Path));
.
.
.
XmlElement chatMessages = doc.CreateElement("ChatMessages");
foreach (Message mess in DataParsed.ChatMessages)
{
XmlElement singleMess = doc.CreateElement("SingleMessage");
singleMess.AppendChild(SerializeElement(doc, "MessageID", mess.MessageID.ToString()));
singleMess.AppendChild(SerializeElement(doc, "MessageName", mess.MessageName));
singleMess.AppendChild(SerializeElement(doc, "MessageTime", mess.MessageTime.ToString()));
singleMess.AppendChild(SerializeElement(doc, "MessageContent", mess.MessageContent));
singleMess.AppendChild(SerializeElement(doc, "MessageTarget", mess.MessageTarget.ToString()));
chatMessages.AppendChild(singleMess);
}
generalVariables.AppendChild(chatMessages);
.
.
.
doc.AppendChild(generalVariables);
//Saving and returning true, serialization successful.
doc.Save(OutputPath + "\\" + ReplayName + ".xml");
return true;
}
catch
{
return false;
}
}

My assumption would be that you're not clearing the DataParsed.ChatMessages object before you pass it in to the function you posted.
Are you sure you're using a new DataParsed object each time? Or are you re-using the same instance and appending more messages to it?

Related

ExceptionLogger with using xml

I am writing to ask you about such question. So i have method which writes exception's info into xml file, but if some exception processed, this method replace all that it is in that file. I want that method write to end file a new info about exception
Code of my method is given below:
public void WriteIntoFile()
{
XDocument xdoc = new XDocument(
new XElement("Exceptions",
new XElement("Exception",
new XElement("Message",this.ErrorMessage.ToString())
)));
xdoc.Save("1.xml");
}
Please, help me with it
This should do the Job, assuming the file exists and you create a new node call "Exceptions".
public void WriteIntoFile(string Message)
{
const string Path = "C:\\Temp\\Log.xml";
XmlDocument MyDocument = new XmlDocument();
MyDocument.Load(Path);
XmlNode ExceptionsNode = MyDocument.CreateElement("Exceptions");
XmlNode ExceptionNode = MyDocument.CreateElement("Exception");
XmlNode MessageNode = MyDocument.CreateElement("Message");
MessageNode.InnerText = Message;
ExceptionNode.AppendChild(MessageNode);
ExceptionsNode.AppendChild(ExceptionNode);
MyDocument.AppendChild(ExceptionsNode);
}
if you want the "Exception"- Node append to a existing "Exceptions" node, use this:
XmlNode ExceptionsNode = MyDocument.SelectSingleNode("/Exceptions");
Greetings from Austria.

C# .Net XML - Object reference not set to an instance of an object - writing value to XML

I am trying to write something to xml file. I have a function:
bool WriteValueTOXML(string pstrValueToRead, string pstrValueToWrite)
{
try
{
XmlTextReader reader = new XmlTextReader("config.ini");
XmlDocument doc = new XmlDocument();
doc.Load(reader);
reader.Close();
XmlNode oldNode;
XmlElement root = doc.DocumentElement;
oldNode = root.SelectSingleNode(#"/settings/" + pstrValueToRead);
oldNode.InnerText = pstrValueToWrite;
doc.Save("config.ini");
return true;
}
catch (NullReferenceException e)
{
MessageBox.Show(e.Message);
return false;
}
}
When I am trying to set InnerText in oldNode (oldNode.InnerText = pstrValueToWrite;) the NullReferenceException is thrown with message "Object reference not set to an instance of an object".
File that I am trying to write to is here:config.ini
oldNode = root.SelectSingleNode(#"/settings/" + pstrValueToRead); must be returning null. Put a break point just after that line of code and check if that's the case. If so, adjust your xpath so it returns an actual node.
This example works with the below assumptions:
XmlDocument doc = new XmlDocument();
using(XmlTextReader reader = new XmlTextReader(#"C:\Temp\config.ini"))
{
doc.Load(reader);
}
XmlElement root = doc.DocumentElement;
XmlNode oldNode = root.SelectSingleNode(#"/settings/database");
oldNode.InnerText = "Blah Blah2";
doc.Save(#"C:\Temp\config.ini.out");
This is assuming you want to update the inner text your path to database of the database tag to something else.

XDocument will not parse html entities (e.g. ) but XmlDocument will

I am currently converting our old parsers that run on XmlDocument to the XDocument. I do this mainly to get the Linq querying and the added linenumber info.
My xml contains an element like this:
<?xml version="1.0"?>
<fulltext>
hello this is a failed textnode
and I don't know how to parse it.
</fulltext>
My problem is that while XmlDocument seems to have no problem reading that node with:
var xmlDocument = new XmlDocument();
var physicalPath = GetPhysicalPath(uploadFolderFile);
try
{
xmlDocument.Load(physicalPath);
}
catch (XmlException xmlException)
{
_log.Warn("Problems with the document", xmlException);
}
The example above parses the document fine but when I try to do:
XDocument xmlDocument;
var physicalPath = GetPhysicalPath(uploadFolderFile);
var xmlStream = new System.IO.StreamReader(physicalPath);
try
{
xmlDocument = XDocument.Load(xmlStream, LoadOptions.SetLineInfo | LoadOptions.SetBaseUri);
}
catch (XmlException)
{
_log.Warn("Trying to clean document for HexaDecimal", xmlException);
}
It fails to read the document because of the character
The special character seems to be allowed in XML version 1.1 but changing the description doesn't help.
I have thought about just parsing the document with XmlDocument and then converting it; but that seems to be counterintuitive. Can anybody help with this problem?
Ok...so I sort of found a solution to this problem.
First of all I try to parse the xml using the following code:
private XDocument GetXmlDocument(String physicalPath)
{
XDocument xmlDocument;
var xmlStream = new System.IO.StreamReader(physicalPath);
try
{
xmlDocument = XDocument.Load(xmlStream, LoadOptions.SetLineInfo);
}
catch (XmlException)
{
//_log.Warn("Trying to clean document for HexaDecimal", xmlException);
xmlDocument = XmlSanitizingStream.TryToCleanXMLBeforeParsing(physicalPath);
}
return xmlDocument;
}
If it fails to load the document, then I will try to clean it using the technique used in this blogpost:
http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/
It will not remove the character I mentioned before, but it will remove any character not allowed by the XML standard.
Then, after sanitizing the XML, I add an XMLReader and set its settings to not check characters:
public static XDocument TryToCleanXMLBeforeParsing(String physicalPath)
{
string xml;
Encoding encoding;
using (var reader = new XmlSanitizingStream(File.OpenRead(physicalPath)))
{
xml = reader.ReadToEnd();
encoding = reader.CurrentEncoding;
}
byte[] encodedString;
if (encoding.Equals(Encoding.UTF8)) encodedString = Encoding.UTF8.GetBytes(xml);
else if (encoding.Equals(Encoding.UTF32)) encodedString = Encoding.UTF32.GetBytes(xml);
else encodedString = Encoding.Unicode.GetBytes(xml);
var ms = new MemoryStream(encodedString);
ms.Flush();
ms.Position = 0;
var settings = new XmlReaderSettings {CheckCharacters = false};
XmlReader xmlReader = XmlReader.Create(ms, settings);
var xmlDocument = XDocument.Load(xmlReader);
ms.Close();
return xmlDocument;
}
Since I've cleaned the document removing illegal characters before I add the ignore characters to the reader, I am pretty sure that I do not read a malformed XML document. Worst case scenario is I get a malformed XML and it will throw an error anyways.
I only use this for parsing and it should only be used to read the data. This will not make the XML well-formed and will in many cases throw exceptions elsewhere in your code. I am only using this because I cannot change what the customer is sending us and I have to read it as is.

How to turn url into XML

I'm trying to use this URL...
http://www.webservicex.net/stockquote.asmx/GetQuote?Symbol=T
It acts like a XML but it isn't in the right format, I want to be able to use it to display it in XML form...
this is my code right now
protected void btnGetResult_Click(object sender, EventArgs e)
{
XPathNavigator nav;
XmlDocument myXMLDocument = new XmlDocument();
String stockQuote = "http://www.webservicex.net/stockquote.asmx/GetQuote?Symbol=T" + txtInfo.Text;
myXMLDocument.Load(stockQuote);
// Create a navigator to query with XPath.
nav = myXMLDocument.CreateNavigator();
nav.MoveToRoot();
nav.MoveToFirstChild();
do
{
//Find the first element.
if (nav.NodeType == XPathNodeType.Element)
{
//Move to the first child.
nav.MoveToFirstChild();
//Loop through all the children.
do
{
//Display the data.
txtResults.Text = txtResults.Text + nav.Name + " - " + nav.Value + Environment.NewLine;
} while (nav.MoveToNext());
}
} while (nav.MoveToNext());
}
Have a look at the source of the response you receive. The content (everything with the rootnode) is no XML. The tags are HTML entities: < and >. Loading that straight into you XmlDocument will treat all the content you are after as simple text.
The following example downloads the online resource, replaces the HTML entities with tags and reloads the XML document, which is then accessible by XPath.
string url = "http://www.webservicex.net/stockquote.asmx/GetQuote?Symbol=T";
XmlDocument doc = new XmlDocument();
doc.Load(url);
string actualXml = doc.OuterXml;
actualXml = actualXml.Replace("<", "<");
actualXml = actualXml.Replace(">", ">");
doc.LoadXml(actualXml);
I haven't considered the second part of your example source code. But I guess having a proper XML document will be the first step.

XmlDocument Save keeps file open

I have a simple c# function that creates a basic XML file and saves:
private void CreateXMlFile(string Filename, string Name, string Company)
{
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode licenseNode = doc.CreateElement("license");
doc.AppendChild(licenseNode);
XmlNode node = doc.CreateElement("Name");
node.AppendChild(doc.CreateTextNode(Name));
licenseNode.AppendChild(node);
node = doc.CreateElement("Company");
node.AppendChild(doc.CreateTextNode(Company));
licenseNode.AppendChild(node);
doc.Save(Filename);
}
When I try to edit or delete the file I always get following error:
The process cannot access the file because it is being used by another
process.
XmlDocument doesnt have any inbuilt dispose or close routines and wondered how I can force the file to close before later editing or deleting it.
I have tried to save the file using StreamWriter:
StreamWriter outStream = System.IO.File.CreateText(outfile);
outStream.Write(data);
outStream.Close();
But this didnt make a difference with the same error.
Your advice is greatly accepted.
Thank you
Send Stream to XmlDocument's Save method instead of file name.
private static void Main(string[] args)
{
CreateXMlFile("c:\\test.xml", "testName", "testCompany");
}
private static void CreateXMlFile(string Filename, string Name, string Company)
{
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode licenseNode = doc.CreateElement("license");
doc.AppendChild(licenseNode);
XmlNode node = doc.CreateElement("Name");
node.AppendChild(doc.CreateTextNode(Name));
licenseNode.AppendChild(node);
node = doc.CreateElement("Company");
node.AppendChild(doc.CreateTextNode(Company));
licenseNode.AppendChild(node);
StreamWriter outStream = System.IO.File.CreateText(Filename);
doc.Save(outStream);
outStream.Close();
}
I tried executing above code and it is working fine at my end.
Your code is fine. I tested it on my machine and there is no lock left after Save().
Try to use Unlocker (http://www.softpedia.com/get/System/System-Miscellaneous/Unlocker.shtml) to check whether you are really the one who holds the lock.
Which .NET framework do you use? Theres also a report (http://bytes.com/topic/net/answers/467028-xmldocument-save-does-not-close-file-properly) which was not reproducable too.

Categories