.Net 2.0/C# で StreamReader を XMLReader オブジェクトに変換する方法
質問
今日私が頭を悩ませてきた簡単な質問です。
.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 の回答の方が近かったです。ただし、両方のソリューションを試した後、私は Longhorn のソリューションによく似たソリューションに傾いています。
解決
よくわかりませんが、XmlReader に渡す前にストリーム内の位置をリセットしていないようです。ストリームから読み取ろうとする前に、ストリームの先頭でシークするようにしてください。また、ストリームにデータを書き込んだ後、ストリームを閉じる/フラッシュする必要がある場合もあります。
編集:
次のコードを試してみたところ、完全に機能しました。
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();
他のヒント
ルート ノードを選択する必要があります。これはデータセットを使用しませんが、私はこの関数を毎日使用しており、うまく機能します。
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;
ぜひ見て使ってください。。
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);
}
}
}
所属していません StackOverflow