Come convertire uno StreamReader in un oggetto XMLReader in .Net 2.0/C#
Domanda
Ecco una domanda veloce contro cui ho sbattuto la testa oggi.
Sto provando a convertire un set di dati .Net in un flusso XML, trasformarlo con un file XSL in memoria, quindi generare il risultato in un nuovo file XML.
Ecco la soluzione attuale:
string transformXML = @"pathToXslDocument";
XmlDocument originalXml = new XmlDocument();
XmlDocument transformedXml = new XmlDocument();
XslCompiledTransform transformer = new XslCompiledTransform();
DataSet ds = new DataSet();
string filepath;
originalXml.LoadXml(ds.GetXml()); //data loaded prior
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb);
transformer.Load(transformXML);
transformer.Transform(originalXml, writer); //no need to select the node
transformedXml.LoadXml(sb.ToString());
transformedXml.Save(filepath);
writer.Close();
Ecco il codice originale:
BufferedStream stream = new BufferedStream(new MemoryStream());
DataSet ds = new DataSet();
da.Fill(ds);
ds.WriteXml(stream);
StreamReader sr = new StreamReader(stream, true);
stream.Position = 0; //I'm not certain if this is necessary, but for the StreamReader to read the text the position must be reset.
XmlReader reader = XmlReader.Create(sr, null); //Problem is created here, the XmlReader is created with none of the data from the StreamReader
XslCompiledTransform transformer = new XslCompiledTransform();
transformer.Load(@"<path to xsl file>");
transformer.Transform(reader, null, writer); //Exception is thrown here, though the problem originates from the XmlReader.Create(sr, null)
Per qualche motivo nel metodo Transformer.Transform, il lettore non ha un nodo radice, infatti il lettore non legge nulla da StreamReader.
La mia domanda è: cosa c'è di sbagliato in questo codice?In secondo luogo, esiste un modo migliore per convertire/trasformare/archiviare un set di dati in XML?
Modificare:Entrambe le risposte sono state utili e tecnicamente quella di aku era più vicina.Tuttavia, mi sto orientando verso una soluzione che assomigli più da vicino a quella di Longhorn dopo aver provato entrambe le soluzioni.
Soluzione
Non ne sono sicuro, ma sembra che tu non abbia reimpostato la posizione nello stream prima di passarlo a XmlReader.Prova a cercare all'inizio del tuo stream prima di provare a leggerlo.Inoltre potrebbe essere necessario chiudere\svuotare il flusso dopo aver scritto alcuni dati su di esso.
MODIFICARE:
Ho appena provato il seguente codice e ha funzionato perfettamente:
BufferedStream stream = new BufferedStream(new MemoryStream());
stream.Write(Encoding.ASCII.GetBytes("<xml>foo</xml>"), 0, "<xml>foo</xml>".Length);
stream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(stream);
XmlReader reader = XmlReader.Create(sr);
while (reader.Read())
{
Console.WriteLine(reader.Value);
}
stream.Close();
Altri suggerimenti
È necessario selezionare il nodo radice.Questo non utilizza i set di dati, ma utilizzo questa funzione tutti i giorni e funziona benissimo.
System.Xml.XmlDocument orgDoc = new System.Xml.XmlDocument();
orgDoc.LoadXml(orgXML);
// MUST SELECT THE ROOT NODE
XmlNode transNode = orgDoc.SelectSingleNode("/");
System.Text.StringBuilder sb = new System.Text.StringBuilder();
XmlWriter writer = XmlWriter.Create(sb);
System.IO.StringReader stream = new System.IO.StringReader(transformXML);
XmlReader reader = XmlReader.Create(stream);
System.Xml.Xsl.XslCompiledTransform trans = new System.Xml.Xsl.XslCompiledTransform();
trans.Load(reader);
trans.Transform(transNode, writer);
XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());
return doc;
per favore guardalo e usalo..
using (MemoryStream memStream = new MemoryStream())
{
memStream.Write(Encoding.UTF8.GetBytes(xmlBody), 0, xmlBody.Length);
memStream.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(memStream))
{
// xml reader setting.
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings()
{
IgnoreComments = true,
IgnoreWhitespace = true,
};
// xml reader create.
using (XmlReader xmlReader = XmlReader.Create(reader, xmlReaderSettings))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LoginInfo));
myObject = (LoginInfo)xmlSerializer.Deserialize(xmlReader);
}
}
}