栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何从XMLType节点提取元素路径?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何从XMLType节点提取元素路径?

您可以通过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


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/382672.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号