簡體   English   中英

如何從 Oracle 中的 XMLType 列中提取特定節點的所有子節點的值(通過輸入參數提供)

[英]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       

db<>小提琴

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM