您可以通过Oracle XML DB
XQuery函数集中的XMLTable函数来实现:
select * from XMLTable( ' declare function local:path-to-node( $nodes as node()* ) as xs:string* { $nodes/string-join(ancestor-or-self::*/name(.), ''/'') }; for $i in $rdoc//name return <ret><name_path>{local:path-to-node($i)}</name_path>{$i}</ret> ' passing XMLParse(content ' <users><user><name>user1</name></user><user><name>user2</name></user><group> <user><name>user3</name></user></group><user><name>user4</name></user> </users>' ) as "rdoc" columns name_path varchar2(4000) path '//ret/name_path', name_value varchar2(4000) path '//ret/name' )对我来说,XQuery看起来至少比XSLT更直观地处理XML数据。
您可以在此处找到有用的XQuery函数集。
更新1
我想您需要在最后阶段使用完全数据的完全纯数据集。可以通过以下逐步构建的复杂方法来实现此目标,但是此变体非常耗资源。我建议审查最终目标(选择一些特定记录,计数元素数量等),然后简化此解决方案或完全更改它。
更新2
除最后一个步骤外,所有其他步骤均从此更新中删除,因为@ABCade在注释中提出了更为优雅的解决方案。下面的 Update 3 部分提供了此解决方案。
第1步 -使用相应的查询结果构建ID的数据集
第2步 -汇总到单个XML行
步骤3- 通过使用XMLTable查询约束的XML,最终获得完整的数据集
with xmlsource as ( -- only for purpose to write long string only once select ' <users><user><name>user1</name></user><user><name>user2</name></user><group> <user><name>user3</name></user></group><user><name>user4</name></user> </users>' xml_string from dual ),xml_table as ( -- model of xmltable select 10 id, xml_string xml_data from xmlsource union all select 20 id, xml_string xml_data from xmlsource union all select 30 id, xml_string xml_data from xmlsource ) select *from XMLTable( ' for $entry_user in $full_doc/full_list/list_entry/name_info return <tuple> <id>{data($entry_user/../@id_value)}</id> <path>{$entry_user/name_path/text()}</path> <name>{$entry_user/name_value/text()}</name> </tuple> ' passing ( select XMLElement("full_list",XMLAgg( XMLElement("list_entry", XMLAttributes(id as "id_value"), XMLQuery( ' declare function local:path-to-node( $nodes as node()* ) as xs:string* { $nodes/string-join(ancestor-or-self::*/name(.), ''/'') };(: function to construct path :) for $i in $rdoc//name return <name_info><name_path>{local:path-to-node($i)}</name_path><name_value>{$i/text()}</name_value></name_info> ' passing by value XMLParse(content xml_data) as "rdoc" returning content ) ) ) ) from xml_table ) as "full_doc" columns id_val varchar2(4000) path '//tuple/id', path_val varchar2(4000) path '//tuple/path', name_val varchar2(4000) path '//tuple/name' )更新3
正如@ABCade在他的评论中提到的那样,将ID与XQuery结果联接起来确实是一种非常简单的方法。
因为我不喜欢答案中的外部链接,所以下面的代码代表了他的SQL提琴,有点适应了此答案中的数据源:
with xmlsource as ( -- only for purpose to write long string only once select ' <users><user><name>user1</name></user><user><name>user2</name></user><group> <user><name>user3</name></user></group><user><name>user4</name></user> </users>' xml_string from dual ),xml_table as ( -- model of xmltable select 10 id, xml_string xml_data from xmlsource union all select 20 id, xml_string xml_data from xmlsource union all select 30 id, xml_string xml_data from xmlsource)select xd.id, x.* fromxml_table xd, XMLTable( 'declare function local:path-to-node( $nodes as node()* ) as xs:string* {$nodes/string-join(ancestor-or-self::*/name(.), ''/'') }; for $i in $rdoc//name return <ret><name_path>{local:path-to-node($i)}</name_path>{$i}</ret> ' passing XMLParse(content xd.xml_data ) as "rdoc" columns name_path varchar2(4000) path '//ret/name_path', name_value varchar2(4000) path '//ret/name' ) x


