473,387 Members | 1,766 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Problem appending a new element to xml file...

Hi all,

I'm trying to distill all of the info from google searches into what I
need, with partial success. In truth, the whole xmlNode, Document,
Element, etc group of classes & methods is going over my head - lol!

The structure of the xml file I'm trying to append to is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!-- stuff -->
<!-- more stuff -->
<Scenarios attr="0">
<Scenario num="0">
<TimeSeries name="cdj" >
<Observation date="01/01/2001" value="1000"/>

a whole bunch more observations

</TimeSeries>
</Scenario>
</Scenarios>

I'm trying to code up a routine that adds another Observation to the
list. Here's what I've got:

public void WriteHistory(HistoryType histype, double val)
{
try
{
XmlDocument cdjDoc = new XmlDocument();
XmlNode parentNode;

cdjDoc.LoadXml(monthlyPath + filename);
parentNode = cdjDoc.DocumentElement;

XmlNode newElement = cdjDoc.CreateNode(XmlNodeType.Element,
"Observation", null);
cdjDoc.AppendChild(newElement);

XmlAttribute date = cdjDoc.CreateAttribute("date");
date.InnerText = DateTime.Now.ToString("MM/dd/yyyy");
newElement.Attributes.Append(date);

XmlAttribute rate = cdjDoc.CreateAttribute("value");
rate.InnerText = val.ToString();
newElement.Attributes.Append(rate);

XmlTextWriter writer = new XmlTextWriter(monthlyPath +
filename,null);
cdjDoc.Save(writer);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message,"Screwed!");
}

This doesn't work - throws an exception with message:

The data at the root level is invalid. Line 1, position 1.

I believe the problem is that I'm not "finding" the proper spot in the
xml structure to AppendChild my new element to. Can someone help me
with this? (Or any other problem, if I'm mistaken in my diagnosis?)

Thanks for any guidance,

cdj

Nov 16 '06 #1
13 2587
You're making it very hard on yourself.

Try this (and note than most of the "code" is the XML block to make it
demonstrable); I have also used a more exotic query in SelectSingleNode
than is probably necessary... depends if you need to select a
*specific* scenario/series; if only one you can drop all the
[@something='value'] stuff...

using System;
using System.Xml;
class Program {
static void Main()
{
const string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>

<Scenarios attr=""0"">
<Scenario num=""0"">
<TimeSeries name=""cdj"" >
<Observation date=""01/01/2001"" value=""1000""/>
<Observation date=""02/02/2001"" value=""2000""/>
<Observation date=""03/03/2001"" value=""3000""/>
</TimeSeries>
</Scenario>
</Scenarios>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml); //TODO: doc.Load(filename);
XmlElement el = (XmlElement)
doc.SelectSingleNode(@"Scenarios[@attr='0']/Scenario[@num='0']/TimeSeries[@name='cdj']");
XmlElement newObservation =
(XmlElement)el.AppendChild(doc.CreateElement("Obse rvation"));
newObservation.SetAttribute("date",
DateTime.Today.ToString("MM/dd/yyyy"));
newObservation.SetAttribute("value",
DateTime.Today.ToString("3000"));

Console.WriteLine(doc.OuterXml); //TODO: doc.Save(filename);
}
}

Nov 16 '06 #2

Marc Gravell wrote:
You're making it very hard on yourself.
Hey! I'm tryin here!

lolol! Just teasin - thanks - I'll give it a whirl!

cdj

Nov 16 '06 #3
Actually, I note your example hints at another level of xml nodes (not
shown)... in which case either include this in the XPath/XQuery, or
replace doc.SelectSingleNode(...) with
doc.DocumentElement.SelectSingleNode(...), which will take you inside
the outer element.

Marc

Nov 16 '06 #4

Marc Gravell wrote:
Actually, I note your example hints at another level of xml nodes (not
shown)... in which case either include this in the XPath/XQuery, or
replace doc.SelectSingleNode(...) with
doc.DocumentElement.SelectSingleNode(...), which will take you inside
the outer element.

Marc
As the example structure I gave indicates, it is theoretically possible
for there to be multiple X's within a given Y for a variety of Y's.

In actual fact, the only case of interest to what I need is the
multiple Observations within a TimeSeries. Or to put it equivalently (I
hope): Observations are the only nodes with siblings.

Thanks again!

cdj

Nov 16 '06 #5
Glad to help - any problems, be sure to get back...

For completeness: your original code touched on XmlWriter; this is
typically used *instead of* the XmlDocument model in those scenarios
where XmlDocument is too heavy - just as very large xml fragments; with
XmlWriter you could write a 500Mb file from a database by writing one
row at a time directly to hte stream; with the XmlDocument you would
need to hold it all in memory first, probably taking about 4-times
that, so 2Gb (better hope for Win64 memory addressing!).
XmlDocument, however, uses the "all in memory" model to provide
services such as XPath/XQuery, and simple element manipulation. There
are other differences, but that is the general principle; for
small-to-mid-size xml, XmlDocument is a reasonable choice.

Marc

Nov 16 '06 #6

Marc Gravell wrote:
Glad to help - any problems, be sure to get back...

For completeness: your original code touched on XmlWriter; this is
typically used *instead of* the XmlDocument model
The biggest problem I'm having now is preserving all of the pretty
tabs/formatting in the xml document. The PreserveWhiteSpace property
does better than nothing, but falls substantially short of what might
be expected. For example, even with PreserveWhiteSpace, a newline is
*not* inserted after the new Observation is added - this surprises me.

Is there a straightforward way to maintain the tab/newline structure?
(It's intuitively obvious what structure I'm talking about - tabs to
indicate hierarchy-level-descent, newlines for new elements.)

You brought up a new issue to me: the xmlDocument vs XmlWriter. The
code I've been working with, per your suggestion (I thought - lol) is:

XmlDocument cdjDoc = new XmlDocument();
cdjDoc.PreserveWhitespace = true;

XmlTextReader reader = new XmlTextReader(monthlyPath + filename);
cdjDoc.Load(reader);
reader.Close();

XmlElement el =
(XmlElement)cdjDoc.SelectSingleNode(@"Scenarios[@version='1']/Scenario[@id='0']/TimeSeries[@name='cdj']");
XmlElement newObservation =
(XmlElement)el.AppendChild(cdjDoc.CreateElement("O bservation"));
newObservation.SetAttribute("date",
DateTime.Today.ToString("MM/dd/yyyy"));
newObservation.SetAttribute("value", val.ToString());

XmlTextWriter writer = new XmlTextWriter(monthlyPath +
filename,null);
cdjDoc.Save(writer);
writer.Close();

Is there a better way to load/save the xml file to/from disk besides
this? Do tell. lol

thanks again!

cdj

Nov 16 '06 #7

sherifffruitfly wrote:
Marc Gravell wrote:
Glad to help - any problems, be sure to get back...

For completeness: your original code touched on XmlWriter; this is
typically used *instead of* the XmlDocument model

The biggest problem I'm having now is preserving all of the pretty
tabs/formatting in the xml document.
Nevermind on the prettyprinting. The following lines, in the right
place, completely suffice for me:

cdjDoc.CreateNode(XmlNodeType.Text, "\n", null);

writer.Formatting = Formatting.Indented;
writer.Indentation = 4;

Thanks for your previous help tho!

cdj

Nov 17 '06 #8
I was going to suggest:

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineHandling = NewLineHandling.Entitize;
using (Stream fs = File.OpenWrite(@"c:\out.xml"))
using (XmlWriter writer = XmlWriter.Create(fs, settings))
{
doc.Save(writer);
writer.Close();
fs.Close();
}

I guess either route achieves the same...

Marc

Nov 17 '06 #9
Or (shorter)

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineHandling = NewLineHandling.Entitize;
using (XmlWriter writer = XmlWriter.Create(@"c:\out.xml",
settings))
{
doc.Save(writer);
writer.Close();
}

Nov 17 '06 #10
Tip:

Use \r\n for new lines, not just \n, as many controls (like TextBox) do
not recognize just \n as new line.

On Fri, 17 Nov 2006 02:08:05 +0100, sherifffruitfly
<sh*************@gmail.comwrote:
>
sherifffruitfly wrote:
>Marc Gravell wrote:
Glad to help - any problems, be sure to get back...

For completeness: your original code touched on XmlWriter; this is
typically used *instead of* the XmlDocument model

The biggest problem I'm having now is preserving all of the pretty
tabs/formatting in the xml document.

Nevermind on the prettyprinting. The following lines, in the right
place, completely suffice for me:

cdjDoc.CreateNode(XmlNodeType.Text, "\n", null);

writer.Formatting = Formatting.Indented;
writer.Indentation = 4;

Thanks for your previous help tho!

cdj


--
Happy Coding!
Morten Wennevik [C# MVP]
Nov 17 '06 #11
Or instead of using \r\n explicitly I prefer to use System.Environment.Newline.

Mark.
--
http://www.markdawson.org
"Morten Wennevik" wrote:
Tip:

Use \r\n for new lines, not just \n, as many controls (like TextBox) do
not recognize just \n as new line.

On Fri, 17 Nov 2006 02:08:05 +0100, sherifffruitfly
<sh*************@gmail.comwrote:

sherifffruitfly wrote:
Marc Gravell wrote:
Glad to help - any problems, be sure to get back...

For completeness: your original code touched on XmlWriter; this is
typically used *instead of* the XmlDocument model

The biggest problem I'm having now is preserving all of the pretty
tabs/formatting in the xml document.
Nevermind on the prettyprinting. The following lines, in the right
place, completely suffice for me:

cdjDoc.CreateNode(XmlNodeType.Text, "\n", null);

writer.Formatting = Formatting.Indented;
writer.Indentation = 4;

Thanks for your previous help tho!

cdj

--
Happy Coding!
Morten Wennevik [C# MVP]
Nov 17 '06 #12
Environment.NewLine

In general a good approach; you sometimes need to be careful that this
doesn't make your code break the spec, though - as some formats explicitely
expect a given line ending; fortunately for xml IIRC the spec makes it fine
to use any of the common line-end combinations.

Note, however, that it can be easier to get the writer to do this via the
settings (as previous) than by having to manually insert *any* explicit form
of new-line. Let the xml-writer worry about it, without needing extra text
nodes in your document...

Marc
Nov 17 '06 #13
Agreed, if a certain EOL sequence is required then you better use the
correct one :-)

Mark.
--
http://www.markdawson.org
"Marc Gravell" wrote:
Environment.NewLine

In general a good approach; you sometimes need to be careful that this
doesn't make your code break the spec, though - as some formats explicitely
expect a given line ending; fortunately for xml IIRC the spec makes it fine
to use any of the common line-end combinations.

Note, however, that it can be easier to get the writer to do this via the
settings (as previous) than by having to manually insert *any* explicit form
of new-line. Let the xml-writer worry about it, without needing extra text
nodes in your document...

Marc
Nov 17 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Fnark! | last post by:
I am creating a shopping cart using PHP Version 4.1.2. I am creating and registering a cart object in a session. The cart object contains an array of arrays called $order whose elements are a...
1
by: Jonathan Taylor | last post by:
I have a large XML file, that is too large to read in to XmlDocument. I need to append data to this XML file without creating a new file, since I don't want to have two copies of the large file...
2
by: Cat | last post by:
How do you go about appending data from a dataset to an existing xml file? I know you can use WriteXML but this writes over any data already existing in the specified file.. Cat
1
by: Ron Adam | last post by:
In my program I have a lot of statements that append elements, but sometimes I don't want to append the element so it requres an if statement to check it, and that requires assigning the returned...
3
by: Jim | last post by:
Could anyone please point me towards some code that allows me to add to an existing XML file using the output of an HTML form. I want to add a form on my website so users can input their email...
2
by: Emmanuel | last post by:
I am writing java application which will store data in XML file..Each time when i execute that program ,previous data will be overidden.. Is it possible to append data to XML file,if anybody knows...
5
by: =?Utf-8?B?SmVmZiBCZWVt?= | last post by:
Before you respond with "just use GetShortPathName" please read the rest. We have an application that places files on a file server using mapped drives as it's path of choice. The reason for...
1
by: ofuuzo1 | last post by:
Hi, Is there anyway I can append a new element to an existing xml without first loading the existing file into a variable, adding the new element into the variable and saving it by overwriting the...
1
by: bkamrani | last post by:
Hi Python gurus, I have installed numpy and interested in testing f2py module using the first example in the documentation. First I tried: C:\test>python "C:\Program...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.