NiteshAgarwal Ответов: 3

Как добавить данные в существующий XML-файл в C#?


У меня есть большой 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>



Может ли кто-нибудь помочь мне, как я могу добавить данные в существующий xml-файл без использования XDocument или XmlDocument. Основная причина этого заключается в том, что размер файла слишком велик, и я не предполагаю загружать полный файл в память и выполнять дальнейшую обработку.

Что я уже пробовал:

Я пытаюсь добавить Data StreamWriter, но он добавляет данные после окончания узла<company & gt;.

F-ES Sitecore

Есть ли причина, по которой вы не хотите использовать XmlDocument? Если вы не хотите использовать then, то вам, возможно, придется использовать комбинацию XmlReader и XmlWriter, где вы читаете с помощью reader и записываете с помощью writer, а когда Вы дойдете до последнего узла employee, напишите еще один, а затем продолжите писать остальную часть документа. Гораздо проще просто использовать XmlDocument или его эквивалент. Там также может быть что-то с linq to xml, что вы можете использовать, если вы google.

NiteshAgarwal

Мой xml-файл содержит большое количество данных. Он также может содержать записи в Лакхах. Вот почему я не хочу использовать XmlDocument. Это может привести к снижению производительности.

NotPolitcallyCorrect

Вы не добавляете данные в файл, вы вставляете. Вы читаете файл строка за строкой в новый файл, пока не дойдете до той части, где вы хотите вставить свои новые данные, вставьте свои новые данные, продолжайте, пока не дойдете до конца файла.

3 Ответов

Рейтинг:
2

Dave Kreskowiak

Вы не можете добавлять данные в XML-файл. Почему? Потому что данные, которые вы добавляете, будут находиться вне закрывающего тега корневого тега документа, тем самым делая недействительным формат XML-файла.

Вы должны вставить эти данные с помощью методов XML, а не файловых методов, как вам уже было сказано в комментариях.


Рейтинг:
1

Patrice T

Если вы подумаете об этом, то ваш файл:

<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>

и вы хотите добавить новый employee, результат должен быть:
<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>

Сравните обе версии, и вы поймете, как должны быть сделаны изменения.
Цитата:
как я могу добавить данные в существующий xml-файл без использования XDocument или XmlDocument.

Если вы не можете использовать эти XML-помощники, вы можете сделать это только вручную.
у вас есть в основном 2 возможности: либо вы создаете новый файл,либо обновляете его.
В обоих случаях необходимо определить, куда будут вставлены новые данные.


NiteshAgarwal

@ppolymorphe Спасибо за ваше предложение. Поскольку мой размер файла слишком велик, именно поэтому я не могу использовать XDocument и XmlDocument, потому что он загрузит весь файл в память. Я ищу решение, где я могу сделать это с помощью XmlReader.

Поскольку я генерирую xml из процесса, поэтому я не могу сделать это вручную.

Рейтинг:
0

Mehedi Shams

Привет Нитеш,

Я предоставляю свое решение, основанное на подходе указателя файла C в C#.

Логика:

1) Откройте файл в потоке.
2) переместите указатель файла на последний узел сотрудника.
3) Добавить новый узел.

Здесь выполняются первые два пункта:

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++;
}
Мы перемещаем указатель файла на 25 символов впереди EOF, так как именно в этот момент мы хотим вставить новую запись сотрудника. Конечные узлы "</employees></company & gt;" имеют длину 25 символов, включая новые строки. Поэтому до этого момента мы вводим нового сотрудника.

Здесь достигается третий пункт:
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();
Пожалуйста, обратите внимание, что вам также нужно включить сюда конечные узлы, так как эта часть просто отбросит что-либо с точки вставки. Пожалуйста, измените значения идентификатора и имени сотрудника соответствующим образом.

В качестве альтернативы чтению байт за байтом вы можете непосредственно перейти к точке вставки. Таким образом, вместо приведенного выше кода следующий код работает точно так же:
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();
Проблема заключается в размере файла; как вы уже упоминали, это довольно большой файл, поэтому он может занять огромное пространство. Пожалуйста, попробуйте оба подхода и посмотрите эффект.

Наконец, не забудьте сохранить резервную копию XML-файла перед применением этого кода.