XML Oracle:从多个重复子节点中提取特定属性
问题描述:
我无法理解其他我看到的问题,因为它们有点不同。XML Oracle:从多个重复子节点中提取特定属性
我从Web服务vi UTL_HTTP获取XML作为响应。 XML具有重复的子节点,我只想提取1个特定值。
响应XML:
<Customer>
<Loyalty>
<Client>
<Identifications>
<Identification>
<Form>Form1</Form>
<value>1234</value>
</Identification>
<Identification>
<Form>Form2</Form>
<value>4442</value>
</Identification>
<Identification>
<Form>Form3</Form>
<value>9995</value>
</Identification>
</Identifications>
</Client>
</Loyalty>
</Customer>
我需要提取的节点<value>
仅其中节点<Form>
= “Form3”。
所以,我的代码中,我收到来自另一个功能
v_ds_xml_response XMLTYPE;
-- Here would lie the rest of the code (omitted) preparing the XML and next calling the function with it:
V_DS_XML_RESPONSE := FUNCTION_CALL_WEBSERVICE(
P_URL => V_DS_URL, --endpoint
P_DS_XML => V_DS_XML, --the request XML
P_ERROR => P_ERROR);
随着该响应,我创建了一个循环来存储值。我试过使用WHERE甚至创建一个类型(下面的V_IDENTIFICATION是类型),但它没有返回任何东西(null)。
for r IN (
SELECT
ExtractValue(Value(p),'/Customer/Loyalty/Client/Identifications/Identification/*[local-name()="Form"]/text()') as form,
ExtractValue(Value(p),'/Customer/Loyalty/Client/Identifications/Identification/*[local-name()="value"]/text()') as value
FROM TABLE(XMLSequence(Extract(V_DS_XML_RESPONSE,'//*[local-name()="Customer"]'))) p
LOOP
V_IDENTIFICATION.FORM := r.form;
V_IDENTIFICATION.VALUE := r.value;
END LOOP;
SELECT
V_IDENTIFICATION.VALUE
INTO
P_LOYALTY_VALUE
FROM dual
WHERE V_IDENTIFICATION.TIPO = 'Form3';
注意,P_LOYALTY_VALUE是从我的程序
答
AAAND我设法找到了解决方案,这是很简单的,只是添加了[文本()= “Form3”] /.../”到谓词中的XPath如
SELECT
ExtractValue(Value(p),'/Customer/Loyalty/Client/Identifications/Identification/*[local-name()="Form"][text()="Form3"]/text()') as form,
ExtractValue(Value(p),'/Customer/Loyalty/Client/Identifications/Identification/Form[text()="Form3"]/.../*[local-name()="value"]/text()') as value
还提取只需将它们直接发送到过程的OUT参数中即可:
P_FORM := r.form;
P_LOYALTY_VALUE := r.value;
答
的OUT参数与此SQL你应该得到所需的值:
with data as
(select '<Customer>
<Loyalty>
<Client>
<Identifications>
<Identification>
<Form>Form1</Form>
<value>1234</value>
</Identification>
<Identification>
<Form>Form2</Form>
<value>4442</value>
</Identification>
<Identification>
<Form>Form3</Form>
<value>9995</value>
</Identification>
</Identifications>
</Client>
</Loyalty>
</Customer>' as xmlval
from dual b)
(SELECT t.val
FROM data d,
xmltable('/Customer/Loyalty/Client/Identifications/Identification'
PASSING xmltype(d.xmlval) COLUMNS
form VARCHAR2(254) PATH './Form',
val VARCHAR2(254) PATH './value') t
where t.form = 'Form3');
答
当您不知道确切的路径时。
select * from
xmltable('for $i in $doc//*/Form
where $i = "Form2"
return $i/../value'
passing
xmltype('<Customer>
<Loyalty>
<Client>
<Identifications>
<Identification>
<Form>Form1</Form>
<value>1234</value>
</Identification>
<Identification>
<Form>Form2</Form>
<value>4442</value>
</Identification>
<Identification>
<Form>Form3</Form>
<value>9995</value>
</Identification>
</Identifications>
</Client>
</Loyalty>
</Customer>') as "doc")
答
要提取您寻找您可以使用下面的XPath表达式的值:
/Customer/Loyalty/Client/Identifications/Identification/Form[text()='Form3']/../value
然后你可以使用XMLTABLE函数来得到结果
SELECT my_value
FROM xmltable(
'/Customer/Loyalty/Client/Identifications/Identification/Form[text()=''Form3'']/../value'
PASSING xmltype(
'<Customer>
<Loyalty>
<Client>
<Identifications>
<Identification>
<Form>Form1</Form>
<value>1234</value>
</Identification>
<Identification>
<Form>Form2</Form>
<value>4442</value>
</Identification>
<Identification>
<Form>Form3</Form>
<value>9995</value>
</Identification>
</Identifications>
</Client>
</Loyalty>
</Customer>')
COLUMNS
my_value VARCHAR2(4000) path '/value'
)