.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