Вы можете управлять XML внутри XPath с помощью синтаксиса FLWOR, но вы также можете использовать XMLTable для извлечения всех значений; или, скорее, две таблицы XML: одна для одноэлементного типа элемента, а вторая необязательная для расширения массива; получить все значения в виде строк; и объедините результаты вместе:
select a.id,
listagg(coalesce(x1.value, x2.value), ' ')
within group (order by coalesce(x1.n, x2.n)) as result
from a
cross apply xmltable (
'(/*[local-name()=$var1][1])'
passing xmltype(col1), 'ConstantInputProperties' as "var1"
columns
n for ordinality,
value varchar2(30) path 'Value[@xsi:type="xsd:int"]',
array xmltype path 'Value[fn:starts-with(@xsi:type, "ArrayOf")]'
) x1
outer apply xmltable (
'Value/*'
passing array
columns
n for ordinality,
value varchar2(30) path '.'
) x2
group by a.id;
ID | RESULT
-: | :-----------------------
1 | 0
2 | 0 1
3 | true true true true true
4 | 1.0000000000
db <> fiddle
n for ordinality
просто дает числовое значение c, которое позволяет вам сохранить исходный под -элементный порядок при агрегировании (так что вы получите 0 1
, а не 1 0
). Если вы не хотите, чтобы к агрегированному значению добавлялись пробелы, просто измените второй аргумент listagg
с ' '
на null
, хотя тогда вы не сможете продать разницу между синглтоном 10 и парой значений с 1 и 0, так что это не кажется очень полезным - не то чтобы агрегированное значение в любом случае кажется таким полезным. Вы можете разделиться на несколько под-XML-таблиц, но это, вероятно, ничего вам здесь не даст; db <> fiddle для информации.
можете ли вы предложить, как передать значение ConstantInputProperties в качестве аргумента и использовать его в качестве переменной во входных данных функции в этом случае EXTRACT (XMLTYPE (col1), '(/ [local-name () = "ConstantInputProperties"] / / text ()) ')
Функция extract()
устарела. Вместо этого используйте XMLQuery; например:
select xmlquery(
'(/*[local-name()=$var1][1])/Value/text()'
passing xmltype(col1), 'ConstantInputProperties' as "var1"
returning content)
from a