У меня есть XML, который выглядит так:
<root>
<uid>789</uid>
<element>
<uid>123</uid>
<sub>
<text>XYZ</text>
</sub>
</element>
</root>
Единственная постоянная вещь - это узел <text>
и тот факт, что узел <uid>
может быть на 2 уровня выше. Остальные узлы могут иметь любое имя, поэтому я не могу использовать полные пути.
На основе узла <text>
мне нужно найти узел <uid>
, который является ближайшим или для простоты на 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)
db <> Fiddle demo