У меня есть огромный кусок XML-данных, которые мне нужно «очистить». Xml выглядит примерно так:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:t>F_ck</w:t>
<!-- -->
<w:t>F_ck</w:t>
<!-- -->
<w:t>F_ck</w:t>
</w:p>
</w:body>
</w:document>
Я хотел бы идентифицировать элементы <w:t>
со значением «F_ck» и заменить это значение чем-то другим. Элементы, которые мне нужно очистить, будут разбросаны по всему документу.
Мне нужно, чтобы код работал как можно быстрее и занимал как можно меньше памяти, поэтому я не хочу использовать подходы XDocument
(DOM), которые я нашел здесь и в других местах.
Данные передаются мне в виде потока, содержащего данные Xml, и моя интуиция подсказывает мне, что мне нужны XmlTextReader
и XmlTextWriter
.
Моя первоначальная идея заключалась в том, чтобы работать в режиме SAX, прогонять данные Xml только вперед и «передавать» их в XmlTextWriter
, но я не могу найти разумный способ сделать это.
Я написал этот код:
var reader = new StringReader(content);
var xmltextReader = new XmlTextReader(reader);
var memStream = new MemoryStream();
var xmlWriter = new XmlTextWriter(memStream, Encoding.UTF8);
while (xmltextReader.Read())
{
if (xmltextReader.Name == "w:t")
{
//xmlWriter.WriteRaw("blah");
}
else
{
xmlWriter.WriteRaw(xmltextReader.Value);
}
}
Приведенный выше код принимает только значение объявления элементов и т. д., поэтому никаких скобок или чего-либо еще. Я понимаю, что мог бы написать код, который конкретно выполнял бы .WriteElement()
, .WriteEndElement()
и т. д. в зависимости от NodeType
, но боюсь, что это быстро приведет к беспорядку.
Итак, вопрос:
Как мне - по-хорошему - передать данные xml, считанные из XmlTextReader
, в XmlTextWriter
, сохраняя при этом возможность манипулировать данными во время передачи?