[英]How to extract value of all the child nodes of a specific node (provided through input parameter) from XMLType Column in Oracle
我們的要求之一是獲取給定特定 XML 節點的所有子節點的值。 我有一個使用 Microsoft SQL 服務器的解決方案,但我在 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 的列之一。
我嘗試在以下解決方案中進行轉換,但它給了我 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
幾個例子:
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>
您可以使用 FLWOR 語法在 XPath 中操作 XML,但您也可以使用 XMLTable 提取所有值; 或者更確切地說,兩個 XMLTable,一個用於 singleton 元素類型,另一個用於數組擴展; 將所有值作為字符串獲取; 並將結果匯總在一起:
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
n for ordinality
僅給出一個數值,可讓您在聚合時保持原始子元素順序(因此您得到0 1
而不是1 0
),如果您不希望將空格添加到聚合值中,則只需更改從' '
到null
的第二個listagg
參數,雖然這樣你就不能出售 singleton 10 和一對 1 和 0 的值之間的差異,所以這似乎不是很有用 - 不是聚合值似乎有用反正真的。
您可以拆分為多個子 XMLTable,但這可能不會在這里為您帶來任何好處; db<>fiddle以獲取信息。
您能否建議如何將 ConstantInputProperties 值作為參數傳遞並將其用作 function 輸入中的變量,在這種情況下 EXTRACT(XMLTYPE(col1), '(/ [local-name()="ConstantInputProperties"]/ /text() )')
extract()
function 已棄用。 改用 XMLQuery; 例如:
select xmlquery(
'(/*[local-name()=$var1][1])/Value/text()'
passing xmltype(col1), 'ConstantInputProperties' as "var1"
returning content)
from a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.