Как извлечь значение всех дочерних узлов указанного c узла (предоставленного через входной параметр) из столбца XMLType в Oracle - PullRequest
0 голосов
/ 03 августа 2020

Одно из наших требований - получить значение всех дочерних узлов заданного c XML узла. У меня есть решение, использующее Microsoft SQL Server, но мне нужно то же самое в Oracle. См. Запрос ниже.

Примечание: если существует более одного дочернего узла, результатом должно быть объединение значений всех отдельных дочерних узлов.


select 
REPLACE(Properties, 'utf-8', 'utf-16'),
CAST(REPLACE(Col1, 'utf-8', 'utf-16') as XML).value('(//*[local-name() = sql:variable("@var2")])[1]', 'varchar(200)')

from A

Ниже приводится образец данных / строка из Col1:

<?xml version="1.0" encoding="utf-8"?><ConstantInputProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Value xsi:type="xsd:int">0</Value></ConstantInputProperties>  

здесь A - это таблица, а Col1 - один из столбцов таблицы A.

Я попытался преобразовать ниже Solution, но он дает мне XML вместо значений.

SELECT col1, 
EXTRACT(XMLTYPE(col1), '(/*[local-name()="ConstantInputProperties"][1])')
FROM A

Пример:

<?xml version="1.0" encoding="utf-8"?><ConstantInputProperties xmlns:xsd="w3.org/2001/XMLSchema" xmlns:xsi="w3.org/2001/XMLSchema-instance"><Value xsi:type="ArrayOfInt"><int>0</int><int>1</int></Value></ConstantInputProperties> 

Expected Output 01

<?xml version="1.0" encoding="utf-8"?><ConstantInputProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Value xsi:type="ArrayOfBoolean"><boolean>true</boolean><boolean>true</boolean><boolean>true</boolean><boolean>true</boolean><boolean>true</boolean></Value></ConstantInputProperties>

Expected Output truetruetruetruetrue


<?xml version="1.0" encoding="utf-8"?><ConstantInputProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Value xsi:type="ArrayOfDecimal"><decimal>1.0000000000</decimal></Value></ConstantInputProperties>

Expected Output 1.0000000000



Ответы [ 2 ]

0 голосов
/ 03 августа 2020

Вы можете управлять 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
0 голосов
/ 03 августа 2020

Несколько примеров:

with a as (
select q'[<?xml version="1.0" encoding="utf-8"?><ConstantInputProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Value xsi:type="xsd:int">0</Value></ConstantInputProperties>  
]' col1 from dual
)
select
   x.*
from 
    a,
    xmltable(
        '//*[local-name()="ConstantInputProperties"][1]' 
        passing xmltype(a.col1)
        columns 
            res xmltype path '.'
) x;

--Result:
RES
------------------------------------------------------------------------------
<ConstantInputProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Value xsi:type="xsd:int">0</Value></ConstantInputProperties>


with a as (
select q'[<?xml version="1.0" encoding="utf-8"?><ConstantInputProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Value xsi:type="xsd:int">0</Value></ConstantInputProperties>  
]' col1 from dual
)
select
   x.*
from 
    a,
    xmltable(
        '//*[local-name()="ConstantInputProperties"]/*/text()' 
        passing xmltype(a.col1)
        columns 
            res xmltype path '.'
) x;

--Result:
RES
--------------------------------------------------------------
<Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:int">0</Value>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...