从SQL生成XML

时间:2011-12-10 15:18:11

标签: .net xml tsql

我怀疑这个答案是如此,但我找不到它。我在WPF应用程序中从SQL 2008 R2生成的一些报告我想导出到XML。 XML的最常见用途是导入Excel。使用TSQL和for xml auto我能够生成一些行,然后在头和根中手动编辑以获得有效的XML文档。我的问题是如何通过C#.NET 4.0 WPF生成有效的XML文件。我只是使用FOR XML AUTO进行查询,然后使用XmlReader迭代行并写入文件?如何获得有效的第一行,根和结束标记?

从前面阅读的内容来看,只处理XMLreader和XMLwriter比LINQ XML更快。 XMLwriter还可以选择直接写入磁盘,因为我可能需要写出多达1,000,000行XML。我现在想的是用SQLdataReader读取数据并用XMLwriter写。有人认为有更快的方法吗?

为John Sanders发布的代码,因为他拒绝了我的努力。约翰后来取消了投票,并提供了我的问题的接受答案。

        XDocument xDoc = new XDocument(
            new XDeclaration("1.0","utf-8", "yes") 
                , new XComment("Gabriel Extract")
                //, new XElement("Documents", new XElement("sDoc", new XAttribute("sID", "1")),
                //    new XElement("sDoc", new XAttribute("sID", "1")
                    //)
                //)
        );
        Debug.WriteLine(xDoc);
        XElement xElementDocs = new XElement("Documents"); 
        XElement xElementsDoc;
        XElement xElementAdd;
        using (SqlConnection connection = new SqlConnection(connString))
        {
            connection.Open();
            SqlCommand command = connection.CreateCommand();
            command.CommandText = "select top 100 sID, sParID, docID, attBeg " + Environment.NewLine +
                ",[addDate],[mimeType],[caseID],[textSize],[textHash],[nativeFileName],[nativeFileSize]" + Environment.NewLine +
                ",[nativeMD5],[nativeUNC],[nativeDateCreate],[nativeDateModify],[nativeExtension]" + Environment.NewLine +
                "from docSVsys with (nolock)";
            SqlDataReader rdr = command.ExecuteReader();
            while (rdr.Read())
            {
                //Debug.WriteLine(rdr.GetInt32(0).ToString());
                xElementsDoc = new XElement("sDoc", new XAttribute("sParID", rdr.GetInt32(1).ToString()), new XAttribute("sID", rdr.GetInt32(0).ToString()));
                xElementsDoc.Add(new XElement("docID", rdr.GetString(2)));
                xElementsDoc.Add(new XElement("attBeg", rdr.GetString(3)));
                xElementDocs.Add(xElementsDoc);
            }
            rdr.Close();
        }
        xElementsDoc = (from xml2 in xElementDocs.Descendants("sDoc")
                        where xml2.Attribute("sID").Value == "2"
                        select xml2).FirstOrDefault();
        Debug.WriteLine(xElementsDoc);
        xElementsDoc.Add(new XElement("SVtext", "value"));
        xElementAdd = new XElement("MVtext1", "value1;value2");
        //xElement.Add(new XElement("value", "value1"));
        //xElement.Add(new XElement("value", "value2"));
        xElementsDoc.Add(xElementAdd);
        xElementsDoc = (from xml2 in xElementDocs.Descendants("sDoc")
                        where xml2.Attribute("sID").Value == "4"
                        select xml2).FirstOrDefault();
        Debug.WriteLine(xElementsDoc);
        xElementsDoc.Add(new XElement("SVtext", "value4"));
        xElementAdd = new XElement("MVtext1", "value41;value42");
        //xElement.Add(new XElement("value", "value1"));
        //xElement.Add(new XElement("value", "value2"));
        xElementsDoc.Add(xElementAdd);
        xDoc.Add(xElementDocs);
        //Debug.WriteLine(xDoc);
        xDoc.Save(@"C:\temp\xDocGabe.xml");

还将构建和XMLwriter版本并比较性能。如果有人表达和感兴趣,我会分享我的发现。

我发现这个问题比面包箱大。我需要从中获取数据的5个fk表用于多值字段。想法是执行6个查询,然后使用rdr.nextresult集读取它们。从SQL角度来看,这是一种有效的方法这种方法需要的是找到使用xml2.Attribute(“sID”)的元素。值==“X”。在1000条记录中,它在几秒钟内完成。 10,000分钟需要几分钟,我需要它扩展到100,000。我遇到的另一个问题是我需要将多值显示为单个值,其值连接并用;分隔。所以我要么需要编写SQL来扁平化这些列,或者编写和XML转换,我不知道该怎么做。或者我可以将这些fk表结果读入DictionaryList并使用XMLwriter(听起来很垃圾但是DictionaryList很快)。目前我正在推出1000个max和Xdocument的功能。 LINQ很方便,但并不总是很快。

3 个答案:

答案 0 :(得分:1)

我相信您可能正在寻找ROOT条款:

SELECT whatever
FROM wherever
FOR XML AUTO, ROOT('rootElementName')

答案 1 :(得分:0)

使用LINQ to XML处理与.NET中的XML相关的任何内容。

http://msdn.microsoft.com/en-us/library/bb387089.aspx

答案 2 :(得分:0)

如果您的答案是易于使用/性能权衡的表现,那么您绝对应该使用FOR XML子句作为在性能良好的msxml库上构建的sql-xml功能,并且针对正向读取进行了优化。