Wpis z mikrobloga

#programowanie #csharp

Momentami mam już naprawdę dość M$ i wiecznych problemów niewiadomego pochodzenia...

Chcę nałożyć transformatę xsl na plik XML aby zrobić z niego HTML i wyświetlić go w przeglądarce WPF. No i wszystko działa. Ale tylko w jednym przypadku:

xslCompiledTransform.Transform("file.xml", "result.html");

A potem:

browser.NavigateToString(File.ReadAllText("result.html"));

I to jest JEDYNY przypadek, gdzie mądre klasy M$ nie srają mi do formatowania tego pliku i nie robią mi potem krzaków w przeglądarce ze zwalonym CSSem. Muszę zapisać tego cholernego XMLa z bazy do pliku po konwersji z base64, potem przerobić go z pliku na plik a potem z tego pliku html dopiero odczytać tekst i browser mi go wtedy dopiero wyświetli poprawnie ¯\_(ツ)_/¯

Natomiast chciałbym aby było tak:

1. XML przechowywany jest w bazie jako jakiś long binary w formie base64.
2. Odczytuję go z bazy i konwertuję na normalną postać. Odpowiada za to taki fragment (pocięty oczywiście):

var reader = command.ExecuteReader();

while (reader.Read())
{
if (!reader.IsDBNull(0))
{
byte[] buffer = (byte[])reader.GetValue(0);
result = Encoding.UTF8.GetString(buffer);
}

}

if (!string.IsNullOrEmpty(result))
{
result = Base64Decode(result);
}

return result;

Na tym etapie zajrzenie w debugu nie wykazuje aby tam się coś dziwnego działo.

3. Przekazuję XMLa w postaci stringu dalej i transformuję go w HTML trzymając go nadal w pamięci:

var xslCompiledTransform = new XslCompiledTransform(true);

var stringXmlReader = new StringReader(xmlToRender); // xmlToRender to result z poprzedniego etapu
var xmlReader = XmlReader.Create(stringXmlReader);

xslCompiledTransform.Load(xsltDocument); // xsltDocument to ścieżka do pliku transormaty, wczytywany w surowej postaci

var stringBuilder = new StringBuilder();
var xmlWriter = XmlWriter.Create(stringBuilder);

xslCompiledTransform.Transform(xmlReader, null, xmlWriter);

browser.NavigateToString(stringBuilder.ToString());

No i jak zrobię to w powyższy sposób to dokument nie dość że ma krzaki na polskich znakach, to jeszcze wali się na poziomie CSS, bo jest poukładany w cały świat. Co mam temu śmieciowi zrobić, żeby bez przerzucania plików po dyskach był w stanie to wyświetlić? Podejrzewam, że to ten cholerny StringBuilder albo StringWriter rozpieprzają mi formatowanie, ale wszystko jest tak ułożone, żeby czasem nie używało się tego zbyt wygodnie (widać ile razy trzeba przerobić obiekt na jakieś inne gówna zanim łaskawie pozwoli go przetransformować).
  • 4
Jak zrobię tak, to wszystko jest poprawnie:

var xslCompiledTransform = new XslCompiledTransform(true);

var stringXmlReader = new StringReader(xmlToRender);
var xmlReader = XmlReader.Create(stringXmlReader);

xslCompiledTransform.Load(xsltDocument);

var stringBuilder = new StringBuilder();
var xmlWriter = XmlWriter.Create(stringBuilder);

File.WriteAllText("C:\dupa\test.xml", xmlToRender);

xslCompiledTransform.Transform("C:\dupa\test.xml", "C:\dupa\result.html");
//xslCompiledTransform.Transform(xmlReader, null, xmlWriter);

//browser.NavigateToString(stringBuilder.ToString());
browser.NavigateToString(File.ReadAllText("C:\dupa\result.html"));

Więc:

1. Na pewno nie ma problemu z plikiem transformaty.
2. Na pewno plik xml jest przemielony z base64 poprawnie.
3. Przeglądarka także działa poprawnie, przynajmniej przy odczycie z pliku.
4. XslCompiledTransform
Dobra, temat jak z elektrody, bo sam sobie odpowiadam xD

Gdy zrobiłem w ten sposób to nagle zaczęło działać:

var xslCompiledTransform = new XslCompiledTransform(true);

var stringXmlReader = new StringReader(xmlToRender);
var xmlReader = XmlReader.Create(stringXmlReader);

xslCompiledTransform.Load(xsltDocument);

var stringBuilder = new StringBuilder();
var xmlWriter = XmlWriter.Create(stringBuilder);

var writer = new StringWriter();

Stream stream = new MemoryStream();
xslCompiledTransform.Transform(xmlReader, null, writer);

browser.NavigateToString(writer.ToString());

StringWriter nie zniekształcił mi formatowania w żaden sposób, natomiast XmlWriter zbudowany na StringBuilderze tak. Czemu?
@bacteria: Na szczęście to moje gówno też działa. Jest prymitywne, ale takie ma być - ma wyświetlić i nic poza tym. Jeszcze tylko będę musiał zlepiać te HTMLe przed wyświetleniem, bo tam może być kilka XMLi na raz, ale już zauważyłem, że wystarczy z każdego przemielonego dokumentu ponad pierwszy wyciąć
a do reszty zrobić konkatenację i ładnie mi śmiga jeden pod drugim.

EDIT. Nawet tego nagłówka z DOCTYPE nie trzeba ciąć,