Click here to Skip to main content
15,867,488 members
Please Sign up or sign in to vote.
1.24/5 (3 votes)
See more:
I have a large xml file that I need to open and needs to add <employee> node inside the <employees> node in the existing file.

Below is the format of my xml.
XML
<company>
	<employees>
		<employee>
			<id>1</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>2</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>3</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>4</id>
			<name>sa</name>
		</employee>
	</employees>
</company>



Can someone help me how I can add the data into existing xml file without using XDocument or XmlDocument. Main reason behind this is file size is too large and I am not suppose to load the complete file into memory and do the further processing.

What I have tried:

I am trying to append the data StreamWriter but it is appending the data after end of <company> node.
Posted
Updated 20-Dec-16 16:58pm
v4
Comments
F-ES Sitecore 20-Dec-16 8:57am    
Is there a reason you don't want to use XmlDocument? If you don't want to use then then you may have to use a combination of XmlReader and XmlWriter where you read using the reader and write out using the writer, and when you've reached the last employee node write another and then continue writing the rest of the document. Far easier to just use XmlDocument or equivalent. There might also be something with linq to xml you can use if you google.
NiteshAgarwal 20-Dec-16 9:00am    
My xml file contains large number of data. It may contain records in Lakhs also. That is why I don't want to use XmlDocument. It may cause the performance degradation.
[no name] 20-Dec-16 10:20am    
You are not appending data to the file, you are inserting. You read the file line by line to a new file until you get to the part where your want to insert your new data, insert your new data, continue until you get to the end of the file.

Hi Nitesh,

I am providing my solution based on C file pointer approach in C#.

Logic:

1) Open the file in a stream.
2) Move the file pointer to the last employee node.
3) Add a new node there.

First two points are accomplished here:
C#
FileStream FStream = new FileStream("Employee.xml", FileMode.Open);

byte[] ReadAByte = new byte[1];
int FilePointerOffset = 0;

while (FilePointerOffset < FStream.Length - 25)
{
    FStream.Read(ReadAByte, 0, 1);
    FilePointerOffset++;
}
We are moving the file pointer to 25 characters ahead of the EOF as that is the point where we want to insert a new employee record. The ending nodes "</employees></company>" are 25 characters long including newlines. So before that point we are inserting the new employee.

The third point is accomplished here:
C#
byte[] WriteSomeBytes = new byte[200];
WriteSomeBytes = Encoding.ASCII.GetBytes("\t\t<employee>" + Environment.NewLine +
                                    "\t\t\t<id>300</id>" + Environment.NewLine +
                                    "\t\t\t<name>sa</name>" + Environment.NewLine +
                                "\t\t</employee>" + Environment.NewLine +
                            "\t</employees>" + Environment.NewLine +
                        "</company>");
FStream.Write(WriteSomeBytes, 0, WriteSomeBytes.Length);
FStream.Close();
Please note that you also need to include the ending nodes here as this part will merely discard anything from the point of inserting. Please modify the values of the employee id and name accordingly.

As an alternate to reading byte by byte, you can directly move to the point of inserting. So in lieu of the above code the following code works the same:
C#
FileStream FStream = new FileStream("Employee.xml", FileMode.Open);
byte[] ReadBytes = new byte[FStream.Length - 25];
FStream.Read(ReadBytes, 0, (int)FStream.Length - 25); // No WHILE loop needed.

byte[] WriteSomeBytes = new byte[200];
WriteSomeBytes = Encoding.ASCII.GetBytes("\t\t<employee>" + Environment.NewLine +
                                    "\t\t\t<id>22200</id>" + Environment.NewLine +
                                    "\t\t\t<name>sa</name>" + Environment.NewLine +
                                "\t\t</employee>" + Environment.NewLine +
                            "\t</employees>" + Environment.NewLine +
                        "</company>");
FStream.Write(WriteSomeBytes, 0, WriteSomeBytes.Length);
FStream.Close();
The problem is the file size; as you mentioned it is a pretty big file, so it might use up a huge space. Please try both approaches and see the effect.

Finally, don't forget to keep a backup of the XML file before applying this code.
 
Share this answer
 
You can't append data to an XML file. Why? Because the data you append will be outside the closing tag of the root tag of the document, thereby invalidating the format of the XML file.

You MUST insert this data using XML methods, not file methods, as you've already been told in the comments.
 
Share this answer
 
If you think about it, your file is:
XML
<company>
	<employees>
		<employee>
			<id>1</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>2</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>3</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>4</id>
			<name>sa</name>
		</employee>
	</employees>
</company>

and you want to add a new employee, the result must be:
XML
<company>
	<employees>
		<employee>
			<id>1</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>2</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>3</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>4</id>
			<name>sa</name>
		</employee>
		<employee>
			<id>5</id>
			<name>sa</name>
		</employee>
	</employees>
</company>

Compare both versions and you should understand how changes must be done.
Quote:
how I can add the data into existing xml file without using XDocument or XmlDocument.

If you can't use those xml helpers, you can only do it manually.
you have basically 2 possibilities, either you create a new file, either you update the file.
In both cases, you need to determine where the new data will be inserted.
 
Share this answer
 
Comments
NiteshAgarwal 21-Dec-16 0:59am    
@ppolymorphe Thanks for your suggestion. Since my file size is too large that is why I cannot use the XDocument and XmlDocument because it will load the complete file into memory. I am looking for a solution where I can do it using XmlReader.

Since I am generating the xml from process so I cannot do it manually.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900