2012-08-06 40 views
0

從SQL Server 2008,使用for xml auto, root('ROOT'), type, elements xsinil得到這個輸出:C#的XmlWriter SQL服務器

<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<node> 
    <nodeid>28</nodeid> 
    <account_no>0</account_no> 
    <address1>15 CANCUN CT</address1> 
    <serial_no>112199543</serial_no> 
    <x_lat>25.95513358000</x_lat> 
    <y_lon>-97.49027147000</y_lon> 
    <alarm> 
    <alarmid>Outage</alarmid> 
    <alarmtime>2012-08-03T16:27:15.830</alarmtime> 
    </alarm> 
<alarm> 
    <alarmid>Restore</alarmid> 
    <alarmtime>2012-08-06T09:41:53.313</alarmtime> 
</alarm> 
</node> 
</ROOT> 

我試圖從SQL Server從C#與XmlWriter得到與上述相同的結果。

這裏是我的代碼:

private void writeXmlToBrowser(DataTable xml) 
{ 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.OmitXmlDeclaration = true; 
    settings.Indent = true; 

    using (XmlWriter writer = XmlWriter.Create(Response.OutputStream, settings)) 
    { 
     if (xml != null) 
     { 
      writer.WriteStartDocument(); 
      writer.WriteStartElement("ROOT", "http://www.w3.org/2001/XMLSchema-instance"); 
      foreach (DataRow row in xml.Rows) 
      { 
       writer.WriteStartElement("node"); 

       foreach (DataColumn col in xml.Columns) 
       { 
        writer.WriteElementString(col.ColumnName, row[col].ToString().Trim()); 
       } 

       writer.WriteEndElement(); 
      } 

      writer.WriteEndElement(); 
      writer.WriteEndDocument(); 
      writer.Flush(); 
     } 
     else 
     { 
      writer.WriteStartDocument(); 
      writer.WriteStartElement("ROOT", "http://www.w3.org/2001/XMLSchema-instance"); 
      writer.WriteEndElement(); 
      writer.WriteEndDocument(); 
      writer.Flush(); 
     } 
    } 
} 

和這段代碼的輸出是這樣的(兩個節點的元素),我只希望它是一樣格式化的SQL Server輸出。

<ROOT xmlns="http://www.w3.org/2001/XMLSchema-instance"> 
<node> 
    <nodeid>28</nodeid> 
    <account_no>0</account_no> 
    <address1>15 CANCUN CT</address1> 
    <serial_no>112199543</serial_no> 
    <alarmid>Outage</alarmid> 
    <alarmtime>8/3/2012 4:27:15 PM</alarmtime> 
    <x_lat>25.95513358000</x_lat> 
    <y_lon>-97.49027147000</y_lon> 
</node> 
<node> 
    <nodeid>28</nodeid> 
    <account_no>0</account_no> 
    <address1>15 CANCUN CT</address1> 
    <serial_no>112199543</serial_no> 
    <alarmid>Restore</alarmid> 
    <alarmtime>8/6/2012 9:41:53 AM</alarmtime> 
    <x_lat>25.95513358000</x_lat> 
    <y_lon>-97.49027147000</y_lon> 
</node> 
</ROOT> 

更新! 這是我使用的代碼。更短,更簡單。

protected void Page_Load(object sender, EventArgs e) 
{ 
    X(); 
    writeXml(); 
} 

private void X() 
{ 
    x = new XmlDocument(); 
    using (SqlConnection con = new SqlConnection(cn)) 
    { 
     using (SqlCommand cmd = new SqlCommand(sqlstring, con)) 
     { 
      con.Open(); 
      using (XmlReader reader = cmd.ExecuteXmlReader()) 
      { 
       x.Load(reader); 
      } 
     } 
    } 
} 

private void writeXml() 
{ 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true; 
    settings.OmitXmlDeclaration = true; 
    using (XmlWriter xr = XmlWriter.Create(Response.OutputStream, settings)) 
    { 
     x.WriteContentTo(xr); 
     xr.Flush(); 
    } 
} 

回答

2

我發現它很容易序列化對象,而不是試圖在代碼中構建它。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 
using System.Xml.Linq; 

namespace SO.XmlSqlServer 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var node = new SqlOutput 
      { 
       NodeId = 28, 
       AccountNumber = 0, 
       AddressLine1 = "15 CANCUN ST", 
       SerialNo = 112156544, 
       XLatitude = 25.23456354, 
       YLongitude = -97.54435453, 
       Alarms = new List<Alarm>(new[] 
       { 
        new Alarm 
        { 
         AlarmId="Outage", 
         AlarmTime=DateTime.Now 
        }, 
        new Alarm 
        { 
         AlarmId="Restore", 
         AlarmTime=DateTime.Now 
        } 
       }) 
      }; 

      XmlSerializer ser = new XmlSerializer(typeof(SqlOutput)); 
      XDocument doc = new XDocument(); 
      using (var writer = doc.CreateWriter()) 
      { 
       ser.Serialize(writer, node); 
      } 
      Console.WriteLine(doc.ToString()); 
      Console.ReadLine(); 
     } 
    } 

    [XmlRoot("node")] 
    public class SqlOutput 
    { 
     [XmlElement("nodeid")] 
     public int NodeId { get; set; } 

     [XmlElement("account_no")] 
     public int AccountNumber { get; set; } 

     [XmlElement("address1")] 
     public string AddressLine1 { get; set; } 

     [XmlElement("serial_no")] 
     public int SerialNo { get; set; } 

     [XmlElement("x_lat")] 
     public double XLatitude { get; set; } 

     [XmlElement("y_lon")] 
     public double YLongitude { get; set; } 

     [XmlElement("alarm")] 
     public List<Alarm> Alarms { get; set; } 
    } 

    public class Alarm 
    { 
     public string AlarmId { get; set; } 
     public DateTime AlarmTime { get; set; } 
    } 

} 
+0

我顯示輸出到瀏覽器窗口而不是控制檯。再加上節點28的數據庫中有兩個條目(因此第二個xml中的兩個節點) – Fonzy 2012-08-06 15:21:11

+0

只需將Console.WriteLine()更改爲HttpRequest.Write()或用於限制代碼的任何方法。 – 2012-08-06 15:29:51

+0

我沒有走這條路線,但它是一個很好的方式,但我只是使用-for xml auto ...返回了xml文檔,並將其返回給C#XmlDocument對象,並通過Response.OutputStream將其寫入XmlWriter 。 – Fonzy 2012-08-06 15:42:44