Синтаксический анализ xml в хранимой процедуре oracle

#xml #oracle

#xml #Oracle

Вопрос:

У меня есть список, внутри которого есть свойство типа списка (адрес). Я отправляю всю информацию в виде xml в базу данных для обновления / вставки сведений в мою таблицу oracle.

Вот формат xml

      DECLARE
  x XMLType := XMLType( '

    <person>   
    <row>       
    <name>Tom</name>       
    <Address>          
    <LocalAddress>           
    <State>California</State>           
    <City>Los angeles</City>          
    </LocalAddress>          
    <LocalAddress>           
    <State>California1</State>           
    <City>Los angeles1</City>          
    </LocalAddress>       
    </Address>   
    </row>   
    <row>       
    <name>Jim</name>       
    <Address>    
    <LocalAddress> 
    <State>California</State>           
    <City>Los angeles</City>      
    </LocalAddress> 
    </Address>   
    </row>
    </person>');
    v_person_name varchar2(1000);
    v_city varchar2(1000);
    BEGIN
      FOR xmlrow IN
      (SELECT column_value AS xml
      FROM TABLE(XMLSequence(x.extract('/person/row')))
      )
    LOOP
      SELECT extractValue(xmlrow,'/row/name/text()')
      INTO v_person_name
      FROM dual;
      DBMS_OUTPUT.put_line(v_person_name);
      FOR address IN
      (SELECT column_value AS xml
      FROM TABLE(xmlsequence(xmlrow.extract('/row/Address/LocalAddress')))
      )
      LOOP
        -- extract address values same as above.
        SELECT extractValue(xmlrow,'/LocalAddress/City/text()')
        INTO v_city
        FROM dual;
        DBMS_OUTPUT.put_line(v_city);
      END LOOP;
    END LOOP;
    END;
  

Как я могу проанализировать весь этот xml в oracle? Я отправляю это как переменную xmltype.

Это выдает мне ошибку компиляции

 Error report -
ORA-06550: line 35, column 27:
PLS-00382: expression is of wrong type
ORA-06550: line 35, column 14:
PL/SQL: ORA-00932: inconsistent datatypes: expected - got -
ORA-06550: line 35, column 7:
PL/SQL: SQL Statement ignored
ORA-06550: line 41, column 37:
PLS-00302: component 'EXTRACT' must be declared
ORA-06550: line 41, column 37:
PLS-00302: component 'EXTRACT' must be declared
ORA-06550: line 41, column 30:
PL/SQL: ORA-00904: "XMLROW"."EXTRACT": invalid identifier
ORA-06550: line 40, column 7:
PL/SQL: SQL Statement ignored
ORA-06550: line 45, column 29:
PLS-00382: expression is of wrong type
ORA-06550: line 45, column 16:
PL/SQL: ORA-00932: inconsistent datatypes: expected - got -
ORA-06550: line 45, column 9:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:n%s"
*Cause:    Usually a PL/SQL compilation error.
  

Пожалуйста, помогите мне решить эту проблему.
Заранее спасибо.

Ответ №1:

Я могу анализировать вложенный xml с помощью этого метода

 SET serveroutput ON format wrapped;
DECLARE
  x XMLType := XMLType(' 
<person>   
<row>       
<name>Tom</name>       
<Address>          
<LocalAddress>           
<State>California</State>           
<City>Los angeles</City>          
</LocalAddress>          
<LocalAddress>           
<State>California1</State>           
<City>Los angeles1</City>          
</LocalAddress>       
</Address>   
</row>   
<row>       
<name>Jim</name>       
<Address>    
<LocalAddress> 
<State>California</State>           
<City>Los angeles</City>      
</LocalAddress> 
</Address>   
</row>
</person>');
BEGIN
  FOR r IN
  (SELECT ExtractValue(Value(p),'/row/name/text()') AS name ,
    Extract(Value(p),'/row/Address') As Address
  FROM TABLE(XMLSequence(Extract(x,'/person/row'))) p
  )
  LOOP
    DBMS_OUTPUT.put_line(r.name);
    FOR row1 IN
    (SELECT ExtractValue(Value(l),'/LocalAddress/City/text()') AS city 
    FROM TABLE(XMLSequence(Extract(r.Address,'/Address/LocalAddress'))) l
    )
    LOOP

      DBMS_OUTPUT.put_line(row1.city);
      -- do whatever you want with r.name, r.state, r.city
    END LOOP;
    -- do whatever you want with r.name, r.state, r.city
  END LOOP;
END;
  

Ответ №2:

Поскольку вы используете тип XML, я предполагаю, что вам нужно получить доступ к отдельным тегам и их соответствующим значениям. Ниже приведен пример кода, который будет выбирать имена из каждой строки с учетом приведенной выше структуры XML. Примечание: xml_in — это просто имя переменной для переменной xmltype в хранимой процедуре.

 select extractValue(column_value,'/row/name/text()') as name
from table (XMLSequence(xml_in.extract('/person/row')));
  

Если вам нужно выполнить вложенный синтаксический анализ, вы также можете сделать:

 for xmlrow in (select column_value as xml from table(xmlsequence(xml_in.extract('/person/row'))))) loop

   select extractValue(xmlrow.xml,'/row/name/text()')
    into v_person_name
     from dual;

    for address in (select column_value as xml from table(xmlsequence(xmlrow.xml.extract('/row/Address/LocalAddress')))) loop
         -- extract address values same as above.
     end loop;
end loop;
  

Комментарии:

1. Спасибо, но как извлечь адресную часть.

2. Просто используйте XPath. Итак, извлеките значение(column_value,’/row/Address/localAddress/State/text()’) и так далее.

3. Это динамический XML, я не знал, сколько локальных адресов я могу получить внутри адреса.

4. Я отредактировал свой код, я попробовал предложенный вами вариант, но он выдает ошибку компиляции.

5. Обновил мой код. Вы должны указать cursor.column_name , поэтому в моем примере это должно быть xmlrow.xml .