問題描述
如何在 .Net 2.0/C# 中將 StreamReader 轉換為 XMLReader 對象 (How to Convert a StreamReader into an XMLReader object in .Net 2.0/C#)
這是我今天一直在思考的一個快速問題。
我正在嘗試將 .Net 數據集轉換為 XML 流,使用內存中的 xsl 文件對其進行轉換,然後輸出結果到一個新的 XML 文件。
這是當前的解決方案:
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();
這是原始代碼:
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)
由於某種原因在transformer.Transform方法中,閱讀器沒有根節點,事實上,讀者並沒有從 StreamReader 中讀取任何內容。
我的問題是這段代碼有什麼問題?其次,有沒有更好的方法將數據集轉換/轉換/存儲為 XML?
編輯:兩個答案都有幫助,從技術上講,aku 更接近。
參考解法
方法 1:
I'm not sure but it seems that you didn't reset position in stream before passing it to XmlReader. Try to seek at the beginning of your stream before trying to read from it. Also it may be necessary to close\flush stream after you wrote some data to it.
EDIT:
Just tried following code and it worked perfectly:
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();
方法 2:
You must select the root node. This doesn't use Datasets, but I use this function everyday and it works great.
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;
方法 3:
please look it and use..
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);
}
}
}
(by Trevor Abell、aku、David Basarab、user1453680)