如何在.Net 2.0/C#中将StreamReader转换为XMLReader对象

5

今天我遇到了一个问题,希望你能帮忙解决。

我正在尝试将一个 .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的解决方案。

3个回答

7

我不确定,但似乎您在将流传递给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();

5
请使用 using(...) { ... } 块来处理 IDisposable 对象,这样人们就不会从你的代码中复制粘贴学习到不良风格 :( 如果您希望答案尽可能简短以便回答大小较小,请在某个地方提到在实际代码中他们应该使用 using - IgorK
我认为对于短的代码片段来说这并不是必要的。例如,大多数MSDN代码示例并没有展示良好的实践方法。人们应该用自己的头脑思考,而不是盲目地复制粘贴别人的代码。此外,额外的括号会使网页上的代码更难阅读。 - aku
@aku,问题在于如果所有的示例都没有使用using,那么新程序员就无法在任何地方看到它,并且必须通过艰苦的方式学习。此外,没有必要创建“StreamReader”,你可以直接将流传递给“XmlReader.Create(stream)”吗? - Peter

2

您必须选择根节点。这不使用数据集,但我每天都使用这个函数,它非常有效。

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;

0
请查看并使用它。
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);

                    }

                }         
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接