簡體   English   中英

XML Oracle:從多個重復的子節點中提取特定屬性

[英]XML Oracle: Extract specific attribute from multiple repeating child nodes

我在理解其他問題時遇到了麻煩,因為它們有些不同。

我從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>

我僅在節點<Form> =“ Form3”的情況下才需要提取節點<value>

因此,在我的代碼中,我收到了另一個函數的響應

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); 

這樣,我創建了一個LOOP來存儲值。 我嘗試使用WHERE甚至創建類型(下面的V_IDENTIFICATION是該類型),但是它沒有返回任何內容(空)。

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是我的過程中的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'
    )

我設法找到了一個非常簡單的解決方案,只是添加了[text()=“ 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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