Сортировка групами
От: .alex Ниоткуда  
Дата: 27.05.20 10:39
Оценка:
Добрый день. В mssql server для разбора подобного .xml-файла:
<?xml version="1.0" encoding="UTF-8"?>
<main>
    <sender>
        <version>1.0</version>
        <msg_date>26/12/2019</msg_date>
        <position>director</position>
        <fio>
            <surname>Pupkin</surname>
            <name>Ivan</name>
            <patronymic>Ivanivich</patronymic>
        </fio>
    </sender>
    <info>
        <org>
            <org_id>1234</org_id>
            <org_name>Organization</org_name>
        </org>
        <msg>
            <factor>777</factor>
            <op>
                <id>1</id>
                <sum>12345.67</sum>
                <doc>
                    <doc_num>1</doc_num>
                    <doc_date>11/05/2019</doc_date>
                </doc>
                <doc>
                    <doc_num>2</doc_num>
                    <doc_date>12/05/2019</doc_date>
                </doc>
                <doc>
                    <doc_num>3</doc_num>
                    <doc_date>13/05/2019</doc_date>
                </doc>
                <member>
                    <id>1</id>
                    <fio>
                        <surname>Sidorov</surname>
                        <name>Andrey</name>
                        <patronymic>Ivanivich</patronymic>
                    </fio>
                </member>
                <member>
                    <id>2</id>
                    <fio>
                        <surname>Petrov</surname>
                        <name>Pert</name>
                        <patronymic>Petrovich</patronymic>
                    </fio>
                </member>
            </op>
            <op>
                <id>2</id>
                <sum>1000</sum>
                <doc>
                    <doc_num>1</doc_num>
                    <doc_date>11/06/2019</doc_date>
                </doc>
                <doc>
                    <doc_num>2</doc_num>
                    <doc_date>12/06/2019</doc_date>
                </doc>
                <doc>
                    <doc_num>3</doc_num>
                    <doc_date>13/06/2019</doc_date>
                </doc>
                <member>
                    <id>1</id>
                    <fio>
                        <surname>Aaa</surname>
                        <name>Bbb</name>
                        <patronymic>Ccc</patronymic>
                    </fio>
                </member>
                <member>
                    <id>2</id>
                    <fio>
                        <surname>Ddd</surname>
                        <name>Eee</name>
                        <patronymic>Fff</patronymic>
                    </fio>
                </member>
            </op>
        </msg>
    </info>
</main>

пишу что-то типа такого:
declare @sCmd nvarchar(max), @sFullPath varchar(max), @x xml

set @sFullPath = 'd:\test.xml'
set @sCmd = N'select @xml = cast(t.data as xml) from OPENROWSET (BULK '+quotename(@sFullPath, N'''') + N', SINGLE_BLOB) t(data)'
exec sp_executesql @sCmd, N'@xml xml output', @x output;

select distinct
    sender.n.value('version[1]', 'varchar(10)') 'sender.version'
    , sender.n.value('msg_date[1]', 'varchar(50)') 'sender.msg_date'
    , sender.n.value('position[1]', 'varchar(40)') 'sender.position'
    , sender.n.value('fio[1]/surname[1]', 'varchar(500)') 'sender.fio.surname'
    , sender.n.value('fio[1]/name[1]', 'varchar(500)') 'sender.fio.name'
    , sender.n.value('fio[1]/patronymic[1]', 'varchar(500)') 'sender.fio.patronymic'

    , info.n.value('org[1]/org_id[1]', 'varchar(100)') 'info.org.org_id'
    , info.n.value('org[1]/org_name[1]', 'varchar(100)') 'info.org.org_name'

    , info.n.value('msg[1]/factor[1]', 'varchar(10)') 'info.msg.factor'

    , info_msg_op.n.value('id[1]', 'varchar(32)') 'info.msg.op.id'
    , info_msg_op.n.value('sum[1]', 'varchar(32)') 'info.msg.op.sum'

    , info_msg_op_doc.n.value('doc_num[1]', 'varchar(32)') 'info.msg.op.doc.doc_num'
    , info_msg_op_doc.n.value('doc_date[1]', 'varchar(32)') 'info.msg.op.doc.doc_date'

    , info_msg_op_member.n.value('id[1]', 'varchar(32)') 'info.msg.op.member.id'
    , info_msg_op_member.n.value('fio[1]/surname[1]', 'varchar(32)') 'info.msg.op_member.fio.surname'
    , info_msg_op_member.n.value('fio[1]/name[1]', 'varchar(32)') 'info.msg.op.member.fio.name'
    , info_msg_op_member.n.value('fio[1]/patronymic[1]', 'varchar(32)') 'info.msg.op.member.fio.patronymic'
from @x.nodes('main') as main(n)
outer apply main.n.nodes('sender') as sender(n) 
outer apply main.n.nodes('info') as info(n)
    outer apply info.n.nodes('msg/op') as info_msg_op(n)
        outer apply info_msg_op.n.nodes('doc') as info_msg_op_doc(n)
        outer apply info_msg_op.n.nodes('member') as info_msg_op_member(n)

и получаю избыточную одномерную табличку (избыточная потому, что у меня в каждом op 3doc и 2member итого 6 строк для каждой op) но мне собственно так и нужно...
Подскажите можно ли на алгоритмическом языке например на с/tinyxml или например на powershell сделать так же? в смысле без кучи циклов и сохранений значений нод во временные переменные...)
Re: Сортировка групами
От: .alex Ниоткуда  
Дата: 27.05.20 10:43
Оценка:
Здравствуйте, .alex, Вы писали:
Извиняюсь за тему сообщения, автоматом подставилось....
Re: Сортировка групами
От: Mihas  
Дата: 27.05.20 12:20
Оценка:
Здравствуйте, .alex, Вы писали:

A>Подскажите можно ли на алгоритмическом языке

C# с его технологией ADO.Net дотягивает до алгоритмического языка?
Re[2]: Сортировка групами
От: .alex Ниоткуда  
Дата: 28.05.20 09:23
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Здравствуйте, .alex, Вы писали:


A>>Подскажите можно ли на алгоритмическом языке

M>C# с его технологией ADO.Net дотягивает до алгоритмического языка?
Да, конечно! Можно и на нем пример...
Re[2]: Сортировка групами
От: .alex Ниоткуда  
Дата: 30.05.20 13:21
Оценка:
Здравствуйте, Mihas, Вы писали:
прошу прощения, но можно пример пожалуйста...
Отредактировано 30.05.2020 13:21 .alex . Предыдущая версия .
Re[3]: Сортировка групами
От: Mihas  
Дата: 01.06.20 07:27
Оценка:
Здравствуйте, .alex, Вы писали:

M>>C# с его технологией ADO.Net дотягивает до алгоритмического языка?

A>Да, конечно! Можно и на нем пример...

Похоже, насчет, плоской таблицы я погорячился. Но, вот, что можно сделать с помощью ADO.Net:
Загрузить весь XML в DataSet. Все элементы (op, doc, member) разложатся по одноименным таблицам. А между таблицами создадутся связи FOREIGN_KEY.
Это дает возможность обрабатывать все экземпляры сущности (например, member) как одну таблицу: пробежаться по строкам в цикле, предварительно отфильтровав их по условию (метод DataTable.Select()). Если же для строки member потребуется получить связанную с ней строку op, то это можно сделать с помощью метода DataRow.GetParentRow(). И в обратную строну: для строки op можно получить связанные с ней строки Member с помощью DataRow.GetChildRow().
ИМХО, построить на этом аналог оператора JOIN, но со своими блекджеками — вполне несложная задача. Больше мороки будет правильно загрузить XML в DataSet.
Re[4]: Сортировка групами
От: .alex Ниоткуда  
Дата: 02.06.20 22:20
Оценка:
Здравствуйте, Mihas, Вы писали:
M>Похоже, насчет, плоской таблицы я погорячился. Но, вот, что можно сделать с помощью ADO.Net:
M>Загрузить весь XML в DataSet. Все элементы (op, doc, member) разложатся по одноименным таблицам. А между таблицами создадутся связи FOREIGN_KEY.
M>Это дает возможность обрабатывать все экземпляры сущности (например, member) как одну таблицу: пробежаться по строкам в цикле, предварительно отфильтровав их по условию (метод DataTable.Select()). Если же для строки member потребуется получить связанную с ней строку op, то это можно сделать с помощью метода DataRow.GetParentRow(). И в обратную строну: для строки op можно получить связанные с ней строки Member с помощью DataRow.GetChildRow().
M>ИМХО, построить на этом аналог оператора JOIN, но со своими блекджеками — вполне несложная задача. Больше мороки будет правильно загрузить XML в DataSet.
Спасибо за совет! Сделать несколько реляционных табличек "автоматом" тоже вариант... Только можно пожалуйста маленький пример кода, ну или ссылку где пример есть...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.