【问题标题】:XML Oracle: Extract specific attribute from multiple repeating child nodesXML Oracle:从多个重复子节点中提取特定属性
【发布时间】:2016-04-27 19:05:43
【问题描述】:

我无法理解我看到的其他问题,因为它们有点不同。

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

我只需要在节点&lt;Form&gt; = "Form3" 的地方提取节点&lt;value&gt;

所以,在我的代码中,我收到了来自另一个函数的响应

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 是我的过程中的一个 OUT 参数

【问题讨论】:

    标签: sql xml oracle plsql


    【解决方案1】:

    使用这个 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');
    

    【讨论】:

      【解决方案2】:

      当您不知道确切的路径时。

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

      【讨论】:

        【解决方案3】:

        要提取您要查找的值,您可以使用以下 XPATH 表达式:

        /Customer/Loyalty/Client/Identifications/Identification/Form[text()='Form3']/../value
        

        Test it here

        然后你可以使用 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'
            )
        

        【讨论】:

          【解决方案4】:

          我设法找到了解决方案,这很简单,只需添加 [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;
          

          【讨论】:

            猜你喜欢
            • 2017-05-24
            • 2013-09-06
            • 1970-01-01
            • 2020-05-05
            • 1970-01-01
            • 2014-08-06
            • 2018-07-30
            • 2012-11-26
            • 1970-01-01
            相关资源
            最近更新 更多