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