如何使用oracle xmltable读取xml文件中同名的多个标签

发布于 2025-01-09 01:59:40 字数 1993 浏览 0 评论 0原文

<Main>
      <text>data</text>
      <conformation>YES</conformation>
      <details>
         <id>1</id>
      </details>
      <details>
         <id>2</id>
      </details>
      <details>
         <id>3</id>
      </details>
      <details>
         <id>4</id>
      </details>
    <child>
     <tax>123</tax>
     <phone>123</phone>
     <details>
        <id>1</id>
     </details>
     <details>
        <id>2</id>
     </details>
     <details>
        <id>3</id>
     </details>
     
    </child>
    <child>
    <details>
         <id>1</id>
      </details>
     <details>
         <id>2</id>
      </details>
    </child>
    <child>
    <details>
         <id>1</id>
      </details>
     <details>
         <id>2</id>
      </details>
    <details>
         <id>3</id>
      </details>
    <details>
    <details>
         <id>4</id>
      </details>
    
    </child>
</Main>

从上面的 xml 中,我想分别获取主标签中 id 标签的所有值,并使用 XMLtable 分别从每个子标签中获取 id 标签的值。

上面的代码片段还将具有此处未包含的名称空间,并将作为巨大的块数据存储在表中

with main_xml as (
   select child_xml from table_name t, xmltable (XMLNAMESPACES
   (default 'http://namespace'),'$d/data' passing xmltype(t.xmldata) as "d" 
    columns child_xml xmltype path '//Main//child') where id =1 ),
    id_data
    AS
    (select id_val from main_xml , xmltable(XMLNAMESPACES
   (default 'http://namespace'),'$c/child' passing xmltype(child_xml) as "c"
    columns child_data varchar2(1) path '//id'))
    select * bulk collect into tabletypecol from id_data;

使用上面的代码,我只能从所有子标签一起获取 id。

<Main>
      <text>data</text>
      <conformation>YES</conformation>
      <details>
         <id>1</id>
      </details>
      <details>
         <id>2</id>
      </details>
      <details>
         <id>3</id>
      </details>
      <details>
         <id>4</id>
      </details>
    <child>
     <tax>123</tax>
     <phone>123</phone>
     <details>
        <id>1</id>
     </details>
     <details>
        <id>2</id>
     </details>
     <details>
        <id>3</id>
     </details>
     
    </child>
    <child>
    <details>
         <id>1</id>
      </details>
     <details>
         <id>2</id>
      </details>
    </child>
    <child>
    <details>
         <id>1</id>
      </details>
     <details>
         <id>2</id>
      </details>
    <details>
         <id>3</id>
      </details>
    <details>
    <details>
         <id>4</id>
      </details>
    
    </child>
</Main>

From the above xml, I want to get all the values of id tags in the Main tag separately and also get values of id tags from each child tag separately using XMLtable.

The above snippet will also have namespace which is not included here and will be stored as hugeclob data in table

with main_xml as (
   select child_xml from table_name t, xmltable (XMLNAMESPACES
   (default 'http://namespace'),'$d/data' passing xmltype(t.xmldata) as "d" 
    columns child_xml xmltype path '//Main//child') where id =1 ),
    id_data
    AS
    (select id_val from main_xml , xmltable(XMLNAMESPACES
   (default 'http://namespace'),'$c/child' passing xmltype(child_xml) as "c"
    columns child_data varchar2(1) path '//id'))
    select * bulk collect into tabletypecol from id_data;

Using above code I can only get ids from all the child tags together.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黑寡妇 2025-01-16 01:59:40

您的 XML 无效,因为它的

开始标记没有匹配的结束标记。如果您修复了该问题并希望使用例如 LISTAGG 等将 id 值聚合在一起,那么您可以在 Oracle 12 中使用:

SELECT d.ids,
       c.ids
FROM   tablename t
       CROSS JOIN LATERAL (
         SELECT LISTAGG(id, ',') WITHIN GROUP (ORDER BY id) AS ids
         FROM   XMLTABLE(
                  '/Main/details'
                  PASSING XMLTYPE(t.xmldata)
                  COLUMNS
                    id NUMBER(5,0) PATH './id'
                )
       ) d
       CROSS JOIN LATERAL (
         SELECT LISTAGG(id, ',') WITHIN GROUP (ORDER BY id) AS ids
         FROM   XMLTABLE(
                  '/Main/child'
                  PASSING XMLTYPE(t.xmldata)
                  COLUMNS
                    child_no FOR ORDINALITY,
                    xml XMLTYPE PATH '.'
                ) x
                CROSS JOIN XMLTABLE(
                  '/child/details'
                  PASSING x.xml
                  COLUMNS
                    id NUMBER(5,0) PATH './id'
                )
         GROUP BY x.child_no
       ) c

哪个输出:

<表类=“s-表”>
<标题>

IDS
IDS


<正文>

1,2,3,4
1,2,3

1,2,3,4
1,2

1,2,3,4
1,2,3,4

注意:我没有包含 BULK COLLECT INTO 子句,因为您没有给出周围 PL/SQL 块的任何详细信息,因此不清楚您期望如何返回值。

db>>fiddle 此处

Your XML is invalid as it has <details> opening tags without matching closing tags. If you fix that and want to aggregate the id values together using, for example, LISTAGG then you can, from Oracle 12, use:

SELECT d.ids,
       c.ids
FROM   tablename t
       CROSS JOIN LATERAL (
         SELECT LISTAGG(id, ',') WITHIN GROUP (ORDER BY id) AS ids
         FROM   XMLTABLE(
                  '/Main/details'
                  PASSING XMLTYPE(t.xmldata)
                  COLUMNS
                    id NUMBER(5,0) PATH './id'
                )
       ) d
       CROSS JOIN LATERAL (
         SELECT LISTAGG(id, ',') WITHIN GROUP (ORDER BY id) AS ids
         FROM   XMLTABLE(
                  '/Main/child'
                  PASSING XMLTYPE(t.xmldata)
                  COLUMNS
                    child_no FOR ORDINALITY,
                    xml XMLTYPE PATH '.'
                ) x
                CROSS JOIN XMLTABLE(
                  '/child/details'
                  PASSING x.xml
                  COLUMNS
                    id NUMBER(5,0) PATH './id'
                )
         GROUP BY x.child_no
       ) c

Which outputs:

IDSIDS
1,2,3,41,2,3
1,2,3,41,2
1,2,3,41,2,3,4

Note: I have not included a BULK COLLECT INTO clause as you have not given any details of surrounding PL/SQL block so it is unclear how you would expect the values to be returned.

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文