XMLTABLE提取元素的posision()

时间:2019-09-02 08:48:54

标签: sql xml oracle

我有类似XML:

<all>
    <cell>
        <data>A</data>
        <data>A1</data>
        <data>A2</data>
        <data>A3</data>
    </cell>
    <cell>
        <data>B</data>
        <data>C</data>
        <data>D</data>
        <data>E</data>
    </cell>
    <cell>
        <data>X</data>
        <data>X</data>
        <data>X</data>
        <data>X</data>
    </cell>
</all>

我想从所有/单元/数据中提取表内容,并提取元素的唯一路径。属性中没有ID或其他唯一标记,而我对唯一路径的想法例如是:

/ all / cell [2] / data [5]

预期结果(示例XML)为:

Content | Path
----------------------
A       |/all/cell[1]/data[1]
A1      |/all/cell[1]/data[2]
A2      |/all/cell[1]/data[3]
A3      |/all/cell[1]/data[4]
B       |/all/cell[2]/data[1]
C       |/all/cell[2]/data[2]
D       |/all/cell[2]/data[3]
E       |/all/cell[2]/data[4]
X       |/all/cell[3]/data[1]
X       |/all/cell[3]/data[2]
X       |/all/cell[3]/data[3]
X       |/all/cell[3]/data[4]

我尝试使用XMLTABLE调用元素的 posision(),但每个元素仅返回“ 1”。

select b.*
  from dropme a,
       xmltable('/all/cell/data' passing
                xmltype(xml_text) columns 
                cmp_old varchar2(200) path 'text()', -- work corect!
                cmp_old1 varchar2(200) path '.', -- work corect! Result is same as cmp_old(upper filed)
                rowcnt number path 'position()', -- return only value "1"
                rowname varchar2(200) path 'name()', -- work corect! Return "data" as result
                parent_rowcnt number path '../position()', -- return only value "1"
                parent_rowname varchar2(200) path '../name()' -- work corect! Return "cell" as result
                ) b;

我不明白为什么它对函数 name() text()起作用,但是 position()存在问题。

我尝试找到 position()或其他提取所有元素的路径和内容的解决方案的问题。

1 个答案:

答案 0 :(得分:3)

使用多个与XMLTABLE相关的FOR ORDINALITY而不是position()

select b.cell_no,
       b.cell_name,
       c.*
from   dropme a
       CROSS JOIN
       xmltable(
         '/all/cell'
         passing xmltype(xml_text)
         columns
           cell_no   FOR ORDINALITY,
           cell_name VARCHAR2(200) PATH 'name()',
           cell      XMLType       PATH '.'
       ) b
       CROSS JOIN
       XMLTABLE(
         '/cell/data'
         PASSING b.cell
         COLUMNS
           cmp_old varchar2(200) path 'text()',
           rowcnt FOR ORDINALITY,
           rowname varchar2(200) path 'name()'
       ) c;
CELL_NO | CELL_NAME | CMP_OLD | ROWCNT | ROWNAME
------: | :-------- | :------ | -----: | :------
      1 | cell      | A       |      1 | data   
      1 | cell      | A1      |      2 | data   
      1 | cell      | A2      |      3 | data   
      1 | cell      | A3      |      4 | data   
      2 | cell      | B       |      1 | data   
      2 | cell      | C       |      2 | data   
      2 | cell      | D       |      3 | data   
      2 | cell      | E       |      4 | data   
      3 | cell      | X       |      1 | data   
      3 | cell      | X       |      2 | data   
      3 | cell      | X       |      3 | data   
      3 | cell      | X       |      4 | data   

db <>提琴here