Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle-XMLTABLE路径获取节点祖先_Sql_Oracle_Xpath_Oracle12c_Xmltable - Fatal编程技术网

Sql Oracle-XMLTABLE路径获取节点祖先

Sql Oracle-XMLTABLE路径获取节点祖先,sql,oracle,xpath,oracle12c,xmltable,Sql,Oracle,Xpath,Oracle12c,Xmltable,我的XML看起来像: <root> <uid>789</uid> <element> <uid>123</uid> <sub> <text>XYZ</text> </sub> </element> </root> 唯一不变的是node,事实上node可以

我的XML看起来像:

<root>
    <uid>789</uid>
    <element>
      <uid>123</uid>
         <sub>
             <text>XYZ</text>
         </sub>
     </element>
</root>
唯一不变的是node,事实上node可以是2级以上的。其余节点可以有任何名称,因此我无法使用完全限定路径

基于节点,我需要找到最接近的节点,或者为了简单起见,在树的上两层

我试过:

WITH cte("XML") AS (
  SELECT '<root>
             <uid>789</uid>
           <element>
            <uid>123</uid>
            <sub>
                <text>XYZ</text>
            </sub>
            </element>
         </root>'
  FROM dual
)
SELECT x.*, c.*
FROM cte c,XMLTable('//text'
          PASSING XMLTYPE(c."XML")
          COLUMNS
           text VARCHAR2(4000) PATH '.'
            --,guid VARCHAR2(40) PATH '../../uid'  -- unsupported XQuery expression
            --,guid VARCHAR2(40) PATH 'ancestor::node()[2]/uid'  
             -- unsupported XQuery expression\
                 ) x  
WHERE text IS NOT NULL;
我正在寻找类似SQL Server的解决方案:

WITH cte("XML") AS (
  SELECT CAST('<root>
             <uid>789</uid>
           <element>
            <uid>123</uid>
            <sub>
                <text>XYZ</text>
            </sub>
            </element>
         </root>' AS XML)
)
SELECT x.value('../../uid[1]', 'VARCHAR(10)') AS uid
     ,s.x.value('.', 'VARCHAR(10)') AS "text"
FROM cte c
CROSS APPLY c."XML".nodes('//text') s(x)

一个可行的解决方案如下:

SELECT x.*, c.*
FROM cte c,XMLTable('//text/../..'
               PASSING XMLTYPE(c."XML")
               COLUMNS
                 text VARCHAR2(4000) PATH 'uid',
                 guid VARCHAR2(40) PATH 'sub/text'
               ) x  
WHERE text IS NOT NULL;

其结果由两列123和XYZ组成。

一个工作溶液如下:

SELECT x.*, c.*
FROM cte c,XMLTable('//text/../..'
               PASSING XMLTYPE(c."XML")
               COLUMNS
                 text VARCHAR2(4000) PATH 'uid',
                 guid VARCHAR2(40) PATH 'sub/text'
               ) x  
WHERE text IS NOT NULL;
它的结果由两列123和XYZ组成。

您应该使用previous-它将返回除任何祖先之外的所有节点。 前一个集合的顺序是从头到尾。 如果您在::uid之前或更一般的::*之前执行此操作,结果将是789123

将一切结合在一起:

WITH cte("XML") AS (
  SELECT '<root>
             <uid>789</uid>
           <element>
            <uid>123</uid>
            <sub>
                <text>XYZ</text>
            </sub>
            </element>
         </root>'
  FROM dual
)
SELECT x.*, c.*
FROM cte c,XMLTable('//text'
          PASSING XMLTYPE(c."XML")
          COLUMNS
           text VARCHAR2(4000) PATH '.'
           ,guid VARCHAR2(40) PATH '(preceding::uid)[last() -1]/data(.)'  -- 2 -levelup            
                 ) x  
WHERE text IS NOT NULL;
您应该使用previous-它将返回除任何祖先之外的所有节点。 前一个集合的顺序是从头到尾。 如果您在::uid之前或更一般的::*之前执行此操作,结果将是789123

将一切结合在一起:

WITH cte("XML") AS (
  SELECT '<root>
             <uid>789</uid>
           <element>
            <uid>123</uid>
            <sub>
                <text>XYZ</text>
            </sub>
            </element>
         </root>'
  FROM dual
)
SELECT x.*, c.*
FROM cte c,XMLTable('//text'
          PASSING XMLTYPE(c."XML")
          COLUMNS
           text VARCHAR2(4000) PATH '.'
           ,guid VARCHAR2(40) PATH '(preceding::uid)[last() -1]/data(.)'  -- 2 -levelup            
                 ) x  
WHERE text IS NOT NULL;

我对它进行了一些修改,使其独立于“子”节点名称,并且它正在工作。我对它进行了一些修改,使其独立于“子”节点名称,并且它正在工作。