Рекурсивный обход xml
От: .alex Ниоткуда  
Дата: 03.02.23 14:14
Оценка:
Есть например вот такой xml:

<?xml version="1.0" encoding="utf-8"?>
<main>
<fio n="attr">
<name>name1</name>
<pasp>
<pi>pi1</pi>
<pi>pi2</pi>
</pasp>
</fio>
<fio n="attr">
<name>name2</name>
</fio>
<sub_node>
<cr>
<val>val1</val>
<val>val2</val>
<extra>
<ex>ex1</ex>
<ex>ex2</ex>
</extra>
</cr>
<cr>
<val>val3</val>
<val>val4</val>
</cr>
</sub_node>
</main>

Мне нужно вывести определенные его элементы в плоскую таблицу по принципу "каждый с каждым". В mssql сервере я делаю это примерно так:
declare @sCmd nvarchar(max), @sFullPath varchar(max), @x xml
set @sFullPath = 'c:\in\test2.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
    fio.n.value('name[1]', 'varchar(32)') 'fio.name'
    , pi_.n.value('.', 'varchar(32)') 'pi_'
 
    , val.n.value('.', 'varchar(5)') 'val'
    , ex.n.value('.', 'varchar(10)') 'ex'
 
from @x.nodes('main') as main(n)
    outer apply main.n.nodes('fio[@n="attr"]') as fio(n)
        outer apply fio.n.nodes('pasp/pi') as pi_(n)
    outer apply main.n.nodes('sub_node/cr') as cr(n)
        outer apply cr.n.nodes('val') as val(n)
        outer apply cr.n.nodes('extra/ex') as ex(n)

Ну и получаемый результат:

name1 pi1 val1 ex1
name1 pi1 val1 ex2
name1 pi1 val2 ex1
name1 pi1 val2 ex2
name1 pi1 val3 NULL
name1 pi1 val4 NULL
name1 pi2 val1 ex1
name1 pi2 val1 ex2
name1 pi2 val2 ex1
name1 pi2 val2 ex2
name1 pi2 val3 NULL
name1 pi2 val4 NULL
name2 NULL val1 ex1
name2 NULL val1 ex2
name2 NULL val2 ex1
name2 NULL val2 ex2
name2 NULL val3 NULL
name2 NULL val4 NULL

А вот теперь вопрос, как это можно сделать в любом алгоритмическом языке? Например vba/c++/java и пр. в которых есть циклы, рекурсия, ну и SelectNodes(), SelectSingleNode()..
Я как понимаю нужно реализовать рекурсивный обход дерева xml, но что-то никак не соображу как... Подскажите пожалуйста...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.