powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / сформировать XML для последующей загрузки в ADO/VBA
19 сообщений из 19, страница 1 из 1
сформировать XML для последующей загрузки в ADO/VBA
    #39406779
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решаю задачу: быстрая выгрузка данных из веб-сервиса (DataTable) в Excel (VBA, ADODB.Recordset)

Для быстрой загрузки XML в ADODB.Recordset необходимо получить XML следующем виде, включая xmlns, ElementType и AttributeType:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
	xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
	xmlns:rs='urn:schemas-microsoft-com:rowset'
	xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
	<s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
		<s:AttributeType name='name_ru' rs:number='1' rs:writeunknown='true'>
			<s:datatype dt:type='string' dt:maxLength='128' rs:maybenull='false'/>
		</s:AttributeType>
		<s:AttributeType name='name_ua' rs:number='1' rs:writeunknown='true'>
			<s:datatype dt:type='string' dt:maxLength='128' rs:maybenull='false'/>
		</s:AttributeType>
		<s:extends type='rs:rowbase'/>
	</s:ElementType>
</s:Schema>
<rs:data>
	<z:row name_ru='Австрия' name_ua='Австрія'/>
	<z:row name_ru='Англия' name_ua='Англія'/>
	<z:row name_ru='Россия' name_ua='Росія'/>
</rs:data>
</xml>



пробовал так - нужные описания не выводит
Код: c#
1.
2.
3.
            DataTable data = new DataTable("phd_data");
            da.Fill(data);
            data.WriteXml(@"c:\qq\1111.xml"); // тут подставлял все значения XmlWriteMode: WriteSchema, IgnoreSchema, DiffGram




загрузка XML в ADO.dataset в VBA выглядит так
Код: vbnet
1.
2.
Set a = New ADODB.Recordset
a.Open xmlDoc



ЗЫ: конечно, при указании XmlWriteMode: WriteSchema описания полей выводятся, но ADO их всё равно не понимает
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39406856
Minatavr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не трудно, приложи, фрагмент XML, выгруженный функцией data.WriteXml().

А решением может быть применение XSLT.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39406879
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://geekswithblogs.net/AnneBougie/archive/2009/07/02/create-an-adodb-recordset-from-xml.aspx
хотя если структура DataTable статична, я бы схему рекордсета зашил бы в XSLT-шаблон, дальше - сохраняем DataTable в XmlDocument, и применяем к нему XSLT - как-то так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
static void Main(string[] args)
{
  var dt = new DataTable("phd_data");
  // имитация dt.Load
  dt.Columns.Add("name_ru", typeof (string));
  dt.Columns.Add("name_ua", typeof(string));
  foreach(var kvp in new Dictionary<string, string>
    {
      {"Австрия", "Австрія"},
      {"Англия", "Англія"},
      {"Россия", "Росія"}
    })
  {
    var dr = dt.NewRow();
    dr[0] = kvp.Key;
    dr[1] = kvp.Value;
    dt.Rows.Add(dr);
  }
  var xd = new XmlDocument();
  using(var xw = xd.CreateNavigator().AppendChild())
    dt.WriteXml(xw);
  var xslt = new XslCompiledTransform();
  using(var sr = new StringReader(Properties.Resources.Transform))
  using(var xr = XmlReader.Create(sr))
    xslt.Load(xr);
  using(var fs = new FileStream(@"D:\Trash\123.xml", FileMode.Create))
  using(var xw = XmlWriter.Create(fs, new XmlWriterSettings{Indent = true, IndentChars = "  "}))
    xslt.Transform(xd, xw);
  Console.WriteLine("done");
  Console.ReadKey();
}


XSLT (хранится в Properties.Resources.Transform):
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:z="#RowsetSchema">
  <xsl:output method="xml" />
  <xsl:template match="/DocumentElement">
    <xml
      xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
      xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
      xmlns:rs="urn:schemas-microsoft-com:rowset"
      xmlns:z="#RowsetSchema">
      <s:Schema id="RowsetSchema">
        <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
          <s:AttributeType name="name_ru" rs:number="1" rs:writeunknown="true">
            <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
          </s:AttributeType>
          <s:AttributeType name="name_ua" rs:number="1" rs:writeunknown="true">
            <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
          </s:AttributeType>
          <s:extends type="rs:rowbase" />
        </s:ElementType>
      </s:Schema>
      <rs:data>
        <xsl:apply-templates />
      </rs:data>
    </xml>
  </xsl:template>
  <xsl:template match="phd_data">
    <z:row>
      <xsl:for-each select="node()">
        <xsl:attribute name="{local-name()}">
          <xsl:value-of select="text()" />
        </xsl:attribute>
      </xsl:for-each>
    </z:row>
  </xsl:template>
</xsl:stylesheet>


XML на выходе:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<?xml version="1.0" encoding="utf-8"?>
<xml
  xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
  xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
  xmlns:rs="urn:schemas-microsoft-com:rowset"
  xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
      <s:AttributeType name="name_ru" rs:number="1" rs:writeunknown="true">
        <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
      </s:AttributeType>
      <s:AttributeType name="name_ua" rs:number="1" rs:writeunknown="true">
        <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
      </s:AttributeType>
      <s:extends type="rs:rowbase" />
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row name_ru="Австрия" name_ua="Австрiя" />
    <z:row name_ru="Англия" name_ua="Англiя" />
    <z:row name_ru="Россия" name_ua="Росiя" />
  </rs:data>
</xml>
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39406910
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Несколько отчетов в экселе (50)
Под каждый - хранимка в бд возвращает набор строк. Авторизацию в бд на каждого юзверя не дают.

Может, подскажете лучший вариант.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407013
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще можно приреференсить к проекту ADODB, залить в рекордсет DataTable, и сохранить его в XML: https://www.codeproject.com/Articles/10503/Simplest-code-to-convert-an-ADO-NET-DataTable-to-a
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407417
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныЕще можно приреференсить к проекту ADODB, залить в рекордсет DataTable, и сохранить его в XML: https://www.codeproject.com/Articles/10503/Simplest-code-to-convert-an-ADO-NET-DataTable-to-a начал смотреть в эту сторону:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
        private void button2_Click(object sender, EventArgs e)
        {
            ADODB.Connection cn = new ADODB.Connection();
            cn.ConnectionString = @"Provider = Microsoft.Jet.OLEDB.4.0;" + 
                                  @"Data Source=D:\work\c#\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\Книга1.xls;" +
                                  @"Extended Properties=Excel 8.0";
            try
            {
                cn.Open();
            }
            catch (Exception ee)
            {
                MessageBox.Show("error [" + ee.Message + "] in [" + ee.Source + "]" + "\n" +
                               cn.ConnectionString);
                return;
            }
            ADODB.Recordset rs = new ADODB.Recordset();
            rs.Open(@"Select * from [Лист1$]", cn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);
            string FileName = @"D:\work\c#\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\export.txt";
            if (File.Exists(FileName)) File.Delete(FileName);
            rs.Save(FileName, ADODB.PersistFormatEnum.adPersistXML);
            MessageBox.Show("Ok");
            return;

        }

вроде получается
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407439
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx
Код: c#
1.
rs.Save(FileName, ADODB.PersistFormatEnum.adPersistXML);

подскажите, коллеги
как этот сформированный XML корректно вернуть web-service'ом?
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407441
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxandreymx
Код: c#
1.
rs.Save(FileName, ADODB.PersistFormatEnum.adPersistXML);

подскажите, коллеги
как этот сформированный XML корректно вернуть web-service'ом?вернуть как результат выполнения метода, имеющего строковый тип, например. или тип байтового массива.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407442
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вместо FileName можно использовать ADODB.Stream, из которого этот байтовый массив легко извлекается.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407456
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Строку я думал... Насчёт ресурсоёкости как оно будет?
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407485
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
andreymx,

А тебе действительно надо в Эксель?
Можно же в HTML, который эксель скушает потом.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407487
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxСтроку я думал... Насчёт ресурсоёкости как оно будет?Ну это ж xml.
Если сохранять в бинарный ADTG, то объем меньше будет и сохранение/загрузка быстрее, нет нужды в/из xml перегонять.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407489
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2andreymx,

А тебе действительно надо в Эксель?
Можно же в HTML, который эксель скушает потом.мне из веб-сервиса в эксель в рекордсет данные перегнать. Буду рад хорошему примеру
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407579
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxначал смотреть в эту сторону:
вроде получается
Какая-то операция на гланды через то место, куда никогда не заглядывает солнце. Файл экселя через рекордсет загнать в XML, чтобы XML отдать веб-сервисом, чтобы клиент снова загнал XML в рекордсет, и от рекордсета снова получил Excel? Начать можно с того, что если в ваших экселях нет эксклюзивных свистелок от версии 2007 и выше, то файл экселя прекрасно сохраняется в свой собственный XML (SpreadsheetML), и прекрасно, бех каких-либо лишних телодвижений, открывает такой XML. Более того, для генерации таких XML вовсе не обязателен сам Excel - достаточно входных данных в виде XML (такие данные может предоставлять, например, запрос от SQL Server или от оракла)+XSLT - у нас энное количество сервисов так генерит вложения для почтовых рассылок по результатам своей отработки. Краткий пример по формированию такого XML можно посмотреть здесь .
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407598
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эксель был приведён только как пример источника данных, т.к. дома у меня других нет.
А задача - передать набор данных из веб-сервиса в эксель. В рекордсет.
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407725
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Веб-сервис твой?
Файл экселя твой?
Рекордсет нужен для экселевского CopyFromRecordset?
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39407781
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyВеб-сервис твой?
Файл экселя твой?
Рекордсет нужен для экселевского CopyFromRecordset?да
Да
И для этого тоже
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39408012
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самый простой способ имхо

на сервере создать "универсальный обработчик" (*.ashx)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    public class Handler1 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            ADODB.Connection cn = new ADODB.Connection();
            cn.ConnectionString = @"Provider";
            cn.Open();

            ADODB.Recordset rs = new ADODB.Recordset();
            rs.Open(context.Request.QueryString["sql"], cn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);

            ADODB.Stream st = new ADODB.Stream();
            st.Type = ADODB.StreamTypeEnum.adTypeBinary;
            rs.Save(st, ADODB.PersistFormatEnum.adPersistADTG);
            st.Position = 0;

            context.Response.ContentType = "application/octet-stream";
            context.Response.BinaryWrite(st.Read());
        }
    }


На клиенте:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Dim http As New MSXML2.XMLHTTP
Dim st As New ADODB.Stream
Dim rs As New ADODB.Recordset

    http.Open "get", "http://localhost/Handler1.ashx?sql=select * from $Лист1", False
    http.send
    
    st.Type = adTypeBinary
    st.Open
    st.Write http.responseBody
    st.Position = 0
    
    rs.Open st
...
Рейтинг: 0 / 0
сформировать XML для последующей загрузки в ADO/VBA
    #39408027
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, поклацаю
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / сформировать XML для последующей загрузки в ADO/VBA
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]