繁体   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