XmlReader/Writer są kolejne strumienie dostępu. Będziesz musiał przeczytać na jednym końcu, przetworzyć strumień, jak chcesz, i napisać go na drugim końcu. Zaletą jest to, że nie trzeba odczytywać całości w pamięci i budować modelu DOM, co można uzyskać za pomocą dowolnego podejścia opartego na XmlDocument.
Ta metoda powinna Ci zacząć:
private static void PostProcess(Stream inStream, Stream outStream)
{
var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " };
using (var reader = XmlReader.Create(inStream))
using (var writer = XmlWriter.Create(outStream, settings)) {
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
writer.WriteStartElement(reader.Prefix, reader.Name, reader.NamespaceURI);
writer.WriteAttributes(reader, true);
//
// check if this is the node you want, inject attributes here.
//
if (reader.IsEmptyElement) {
writer.WriteEndElement();
}
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.SignificantWhitespace:
writer.WriteWhitespace(reader.Value);
break;
}
}
}
}
To nie jest tak czysty, jak pochodzący własną XmlWriter, ale uważam, że jest to o wiele łatwiejsze.
[EDIT]
Przykładem, jak można otworzyć dwa strumienie na raz może być coś takiego:
using (FileStream readStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write)) {
using (FileStream writeStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Write)) {
PostProcess(readStream, writeStream);
}
}
Dzięki za odpowiedź, pomyślałem (mam nadzieję), że byłaby to miła prosta operacja. Nie mogę być jedyną osobą, która kiedykolwiek chciała czytać w XML do pewnego elementu, edytować go, a następnie wypisać zmieniony wynik. - Jeśli słyszysz więcej przekleństw niż zwykle w Reading dzisiaj .... to ja !! –
@ Hill: Łatwo to zrobić, po prostu nie w streamingu Obawiam się :( –
Subclassing 'XmlReader' (właściwie ty podklasę' XmlTextReader', chyba że masz ochotę wdrożyć wiele abstrakcyjnych metod) jest interesujące wyzwanie: –