0

从 SQL Server 2008 开始,用于for xml auto, root('ROOT'), type, elements xsinil获取此输出:

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

我试图从 C# 的 SQL Server 中获得与上述相同的结果,带有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();
    }
}
4

1 回答 1

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

}
于 2012-08-06T15:15:55.143 回答