Pracuję ze starszą aplikacją, która nie importuje skróconych pustych elementów xml. Na przykład:Jak używać XmlWriterSettings() przy użyciu zastępowania void WriteEndElement()?
BAD pusty:
<foo />
DOBRY pusty:
<foo></foo>
Wiem, że rozwiązanie to osiągnąć, które przedstawię teraz:
public class XmlTextWriterFull : XmlTextWriter
{
public XmlTextWriterFull(Stream stream, Encoding enc) : base(stream, enc)
{
}
public XmlTextWriterFull(String str, Encoding enc) : base(str, enc)
{
}
public override void WriteEndElement()
{
base.WriteFullEndElement();
}
}
i kod klienta:
var x_settings = new XmlWriterSettings();
x_settings.NewLineChars = Environment.NewLine;
x_settings.NewLineOnAttributes = true;
x_settings.NewLineHandling = NewLineHandling.Replace;
x_settings.CloseOutput = true;
x_settings.Indent = true;
x_settings.NewLineOnAttributes = true;
//var memOut = new MemoryStream();
var writer = new XmlTextWriterFull(outputFilename, Encoding.UTF8); //Or the encoding of your choice
var x_serial = new XmlSerializer(typeof(YOUR_OBJECT_TYPE));
x_serial.Serialize(writer, YOUR_OBJECT_INSTANCE);
writer.Close();
Jednakże, jeśli zaobserwowałeś ostrożnie, XmlWriterSettings
nigdy nie są używane w kodzie klienta. Dlatego wyjściowe dane XML są strasznie sformatowane. Moje pytania są następujące: w jaki sposób mogę dostosować powyższy kod do akceptacji XmlWriterSettings
?
Stosowanie metod tworzenia fabryki i klas szczelnych/wewnętrznych/abstrakcyjnych utrudnia implementację zastąpienia.
Przyjmuję alternatywne rozwiązanie, nie jestem żonaty z powyższym rozwiązaniem.
- obejście problemu
Krok 1: tworzenie następujące klasy w roztworze:
public class XmlTextWriterFull : XmlTextWriter
{
public XmlTextWriterFull(TextWriter sink) : base(sink)
{
Formatting = Formatting.Indented;
}
public override void WriteEndElement()
{
base.WriteFullEndElement();
}
}
Krok 2: Dodaj następujący kod klienta. Upewnij się, aby zastąpić YOUR_OBJECT_TYPE i YOUR_OBJECT_INSTANCE z klasą i przykład swojej pracy z:
TextWriter streamWriter = new StreamWriter(outputFilename);
var writer = new XmlTextWriterFull(streamWriter);
var x_serial = new XmlSerializer(typeof (YOUR_OBJECT_TYPE));
x_serial.Serialize(writer, YOUR_OBJECT_INSTANCE);
writer.Close();
Rozwiązaniem powyżej będzie produkować następujący element pusty xml formatowania:
<foo>
</foo>
Problem z tym obejściem problemu jest, że dodaje wiersz (zauważ, że elementy są w oddzielnych wierszach). To może być dla ciebie akceptowalne, ale powoduje problemy z moją starszą aplikacją.
Nie wiem, czy rozwiązuje to ten szczególny przypadek , ale możesz użyć przeciążenia XmlWriter.Create, które pobiera istniejący program piszący i ustawienia. Możesz przekazać własną implementację do tej metody. Według http://msdn.microsoft.com/en-us/library/a09119h4.aspx umożliwia to "dodanie dodatkowych funkcji do bazowego obiektu XmlWriter", ale nie wiem, czy to obejmuje formatowanie. – fsimonazzi
Nie byłem w stanie odpowiedzieć na moje własne pytanie. Ale znalazłem dopuszczalne rozwiązanie. Opublikuję to tutaj, aby, miejmy nadzieję, pomóc komuś innemu; jednak nadal chcę rozwiązania mojego pytania. Moje obejście nie używa XmlWriterSettings, czego właśnie chcę. – sapbucket
Aktualizacja: moja starsza aplikacja nie akceptuje powyższego obejścia, ponieważ pełny znacznik ma wstawiony element posuwu liniowego; dlatego tagi pojawiają się w osobnych wierszach. Publikuję nagrodę, aby sprawdzić, czy mogę zwrócić większą uwagę na to pytanie. –
sapbucket