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

Posted

技术标签:

【中文标题】如何在 .Net 2.0/C# 中将 StreamReader 转换为 XMLReader 对象【英文标题】:How to Convert a StreamReader into an XMLReader object in .Net 2.0/C# 【发布时间】:2010-09-07 15:31:43 【问题描述】:

这是我今天一直在思考的一个快速问题。

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

aku,拜托,拜托,使用 using(...) ... 块为 IDisposables 这样人们就不会复制粘贴您的代码并从中学习不良风格:( 如果您想保留它尽可能简短地提到在实际代码中应该使用usings 的地方。 我认为短代码sn-ps没有必要。例如,大多数 MSDN 代码示例都没有展示好的做法。人们应该用头脑思考,而不是盲目地复制粘贴某人的代码。此外,额外的大括号会降低网页上代码的可读性。 @aku,问题是如果所有示例都丢失了,那么新程序员将不会在任何地方看到它,并且必须以艰苦的方式学习它,也不需要创建“StreamReader”你可以将流传递到“XmlReader.Create(stream)”吗?【参考方案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;

【讨论】:

【参考方案3】:

请查看并使用..

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);

                    

                         
            

【讨论】:

以上是关于如何在 .Net 2.0/C# 中将 StreamReader 转换为 XMLReader 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java Stream 中将 POJO 的列表转换为 Map<String,List>?

在 Java 中将 Stream 转换为字符串

IIS 注册 ASP.NET 2.0 4.0

如何在 .Net 中将区域性更改为 DateTimepicker 或日历控件

如何在 java 中将 Int 转换为 Int[]?

如何在c#.net中将图像文件(如扫描副本)转换为文本文件[重复]