for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Л и с о в о д ы   в с е х   с т р а н,  о б ъ е д и н я й т е с ь !!!  

Список Форумов  :: Не фоксом единым
   :: Помощь сайту :: 

И ещё Oracle + XML
S-type
Автор

Сообщений: 2353
Дата: 02.11.17 16:37:15ОтветитьЦитировать
Есть XML:

  
  <?xml version="1.0" encoding="windows-1251"?>  
  <response>  
    <data>  
      <Документ ВерсФорм="4.02" ИдДок="5CFC2923-A98D-E19A-E053-0200640AB0D8" ИдЗапросФ="355847376">  
        <КодОбр>52</КодОбр>  
      </Документ>  
    </data>  
  [...]

Мне нужно значение КодОбр. Извлекаю его:

l_xresponse.extract('//response/data/Документ/КодОбр/text()').getStringVal();

Дошёл в цикле до документа, в котором:

  
  <?xml version="1.0" encoding="windows-1251"?>  
  <response>  
    <data>  
      <Документ ВерсФорм="4.02" ИдДок="5CFC2923-A98D-E19A-E053-0200640AB0D8" ИдЗапросФ="355847376" КодОбр="51"/>  
    </data>  
  [...]

Как можно вытащить КодОбр?

И ещё вопрос. Приходится extract оборачивать в begin + exception, что неудобно. Можно извлекать так, что бы возвращалось пусто, без перехвата исключения?
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
S-type
Автор

Сообщений: 2353
Дата: 02.11.17 16:52:41ОтветитьЦитировать
Вытащить КодОбр можно так:

extract('//response//data//Документ/@КодОбр')
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
Igor Korolyov

Сообщений: 32006
Дата: 02.11.17 18:53:08ОтветитьЦитировать
Что-то типа
(//Документ/КодОбр/text()|//Документ/@КодОбр)[1]
Объединяет оба результата поиска и потом выбирает первый из них.
Писать полный путь по иерархии не обязательно - разве что у тебя там на разных уровнях в разных ветках этот "Документ" живёт, и нужна именно ветка по указанному пути.
Если не хочешь обрабатывать ошибки, то проверяй то что шаг .extract() вернул не NULL (хоть что-то нашёл) прежде чем у возвращённого объекта метод getStringVal() дёргать.


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
S-type
Автор

Сообщений: 2353
Дата: 03.11.17 22:07:54ОтветитьЦитировать
Спасибо.
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
ВладимирС

Сообщений: 1216
Дата: 13.01.18 08:59:07ОтветитьЦитировать
Что-то у меня не получается парсить XML. Может великие гуру помогут.
И так, имею XML, понятно взял попроще:

Хочу получить результат в виде таблицы:
claim_CODE | applications_CODE | constructions_CODE
...................................................
   413              877                1666
   413              877                1668
   413              877                1667
   413              878                1688
   413              879                1690
   413              879                1689
   413              880                1691
   413              881                1692
   413              882                1694
   413              882                1693
   413              883                1695

Получаю результат:
claim_CODE | applications_CODE
..............................
    413            877
    413            878
    413            879
    413            880
    413            881
    413            882
    413            883

А как написать запрос на желаемый результат ?
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
ВладимирС

Сообщений: 1216
Дата: 13.01.18 09:25:04ОтветитьЦитировать
Можно теги получить:
Результат:
claim_CODE | applications_CODE | constructions_CODE
...................................................
   413             877           <code>1666</code><code>1668</code><code>1667</code>
   413             878           <code>1688</code>
   413             879           <code>1690</code><code>1689</code>
   413             880           <code>1691</code>
   413             881           <code>1692</code>
   413             882           <code>1694</code><code>1693</code>
   413             883           <code>1695</code>
С дальнейшим парсить "constructions_CODE"...
Но XML на самом деле намного сложнее и такой подход конечно возможен, но как то непривлекателен.
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
Igor Korolyov

Сообщений: 32006
Дата: 13.01.18 13:28:47ОтветитьЦитировать
....  
  SELECT CLAIM.EXTRACT('claim/code/text()').GETSTRINGVAL() CLAIM_CODE,  
         APPLICATION.EXTRACT('applications/code/text()').GETSTRINGVAL() APPLICATION_CODE,  
         CONSTRUCTION.EXTRACT('constructions/code/text()').GETSTRINGVAL() CONSTRUCTION_CODE  
    FROM T,  
         TABLE(XMLSEQUENCE(EXTRACT(T.X, 'claim'))) CLAIM,  
         TABLE(XMLSEQUENCE(CLAIM.EXTRACT('claim/applications'))) APPLICATION,  
         TABLE(XMLSEQUENCE(APPLICATION.EXTRACT('applications/constructions'))) CONSTRUCTION;

По идее следует переходить на использование XMLTable, нечто типа вот такого
....  
  SELECT CLAIM.CLAIM_CODE,  
         APPLICATION.APPLICATION_CODE,  
         CONSTRUCTION.CONSTRUCTION_CODE  
    FROM T  
         INNER JOIN  
         XMLTABLE('/claim' PASSING T.X  
           COLUMNS  
             CLAIM_CODE NUMBER PATH 'code',  
             APPLICATIONS XMLTYPE PATH 'applications') CLAIM ON 1 = 1  
         LEFT JOIN  
         XMLTABLE('/applications' PASSING CLAIM.APPLICATIONS  
           COLUMNS  
             APPLICATION_CODE NUMBER PATH 'code',  
             CONSTRUCTIONS XMLTYPE PATH 'constructions') APPLICATION ON 1 = 1  
         LEFT JOIN  
         XMLTABLE('/constructions' PASSING APPLICATION.CONSTRUCTIONS  
           COLUMNS  
             CONSTRUCTION_CODE NUMBER PATH 'code') CONSTRUCTION ON 1 = 1;
Но могут быть нюансы. Скажем по твоей структуре вместо LEFT JOIN с "тупым" условием связывания, т.к. все уровни заполнены (нет applications без constructions, ну и нет только claim/code без applications), можно было бы применить CROSS JOIN, или тот самый "старый" синтаксис с перечислением через запятую... Но скажем на версии 11.2.0.2/Win32 это стабильно валит серверный процесс в ORA-600 А на более свежей 12.1.0.2/Linux64 с некоторыми патчами уже работает как положено... Так что проверяй на своих версиях что будет работать стабильнее.
Есть ещё процедурный подход - используя пакет DBMS_XMLDOM, может оказаться более эффективным (а если "структура" XML-ей нестабильна/разнообразна/произвольна, то ещё и проще, т.к. не потребует "динамики" в SQL запросах использующих XML* функции).
P.S. Если XML документы предполагаются гигантские - по десяткам/сотням Мб - то стоит писать процедурный код разбора используя SAX парсер - но это уже чисто на Java (Java классы можно "встроить" в СУБД).


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
ВладимирС

Сообщений: 1216
Дата: 13.01.18 16:37:46ОтветитьЦитировать
Igor Korolyov !
Супер, БОЛЬШОЕ ТЕБЕ СПАСИБО !
Как сам не догадался. Блин...
Второй запрос проанализирую...
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
keisov

Сообщений: 3
Дата: 25.01.18 16:24:44ОтветитьЦитировать
ВладимирС
Поздравляю)
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
ВладимирС

Сообщений: 1216
Дата: 25.09.18 11:53:22ОтветитьЦитировать
Не выходит что-то каменный цветок.
Чего-то недопонимаю.
Опять прошу помощи.

И так, будут присылаться XML файлы, которые нужно будет парсить, вытаскивать значения и загружать в таблицу.
Но, что-то попробовал на тестовой XML вытаскивать данные и не получается...
XMLTYPE принимает нормально.
Но только начинаем идти по тегам, результаты запроса выдаются пустыми.
SELECT ex.EXTRACT('export').GETSTRINGVAL() TEG_export  
  FROM T,  
  TABLE(XMLSEQUENCE(EXTRACT(T.X, 'export'))) ex

SELECT nsiOKPDList.EXTRACT('nsiOKPDList').GETSTRINGVAL() TEG_nsiOKPDList  
  FROM T,  
  TABLE(XMLSEQUENCE(EXTRACT(T.X, 'export'))) ex,  
  TABLE(XMLSEQUENCE(ex.EXTRACT('export/nsiOKPDList'))) nsiOKPDList

SELECT nsiOKPD.EXTRACT('nsiOKPD').GETSTRINGVAL() TEG_nsiOKPD  
  FROM T,  
  TABLE(XMLSEQUENCE(EXTRACT(T.X, 'export'))) ex,  
  TABLE(XMLSEQUENCE(ex.EXTRACT('export/nsiOKPDList'))) nsiOKPDList,  
  TABLE(XMLSEQUENCE(nsiOKPDList.EXTRACT('nsiOKPDList/nsiOKPD'))) nsiOKPD
И т.д....
Чувствую дело в Namespaces строки:
<export xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://zakupki.gov.ru/oos/export/1" xmlns:oos="http://zakupki.gov.ru/oos/types/1">
Но как это переработать, не знаю.
Как получить значения тегов всех <nsiOKPD> типа ?:
<oos:id>3321</oos:id>  
  <oos:parentId>3291</oos:parentId>  
  <oos:code>01.11.13</oos:code>  
  <oos:parentCode>01.11.1</oos:parentCode>  
  <oos:name>Кукуруза</oos:name>  
  <oos:comment>Эта группировка не включает: ....</oos:comment>  
  <oos:actual>true</oos:actual>



Исправлено: ВладимирС, 25.09.18 11:54
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
Igor Korolyov

Сообщений: 32006
Дата: 26.09.18 21:08:59ОтветитьЦитировать
www.liberidu.com


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: И ещё Oracle + XML
ВладимирС

Сообщений: 1216
Дата: 27.09.18 06:04:04ОтветитьЦитировать
Igor Korolyov !
Большое спасибо!

Оставлю на память:
SELECT R.ID,R.PARENT_ID,R.CODE,R.PARENT_CODE,R.NAME,R.DESCRIPTION,  
      CASE WHEN actual = 'true' THEN 1  
          WHEN actual = 'false' THEN 0  
          ELSE Null  
      END IS_ACTUAL  
  FROM  
  (SELECT XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>    
    <export xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://zakupki.gov.ru/oos/export/1" xmlns:oos="http://zakupki.gov.ru/oos/types/1">    
        <nsiOKPDList>    
            <nsiOKPD>    
                <oos:id>3284</oos:id>    
                <oos:code>Раздел A</oos:code>    
                <oos:name>ПРОДУКЦИЯ СЕЛЬСКОГО ХОЗЯЙСТВА, ОХОТЫ И ЛЕСНОГО ХОЗЯЙСТВА</oos:name>    
                <oos:actual>true</oos:actual>    
            </nsiOKPD>    
            <nsiOKPD>    
                <oos:id>3286</oos:id>    
                <oos:parentId>3284</oos:parentId>    
                <oos:code>Подраздел AА</oos:code>    
                <oos:parentCode>Раздел A</oos:parentCode>    
                <oos:name>ПРОДУКЦИЯ СЕЛЬСКОГО ХОЗЯЙСТВА, ОХОТЫ И ЛЕСНОГО ХОЗЯЙСТВА</oos:name>    
                <oos:actual>false</oos:actual>    
            </nsiOKPD>    
            <nsiOKPD>    
                <oos:id>3321</oos:id>    
                <oos:parentId>3291</oos:parentId>    
                <oos:code>01.11.13</oos:code>    
                <oos:parentCode>01.11.1</oos:parentCode>    
                <oos:name>Кукуруза</oos:name>    
                <oos:comment>Эта группировка не включает:    
    - кукурузу сахарную (см. 01.12.13.150)    
    - кукурузу кормовую (см. 01.11.60.170)</oos:comment>    
                <oos:actual>true</oos:actual>    
            </nsiOKPD>    
        </nsiOKPDList>    
    </export>') xml_data FROM DUAL  
  ),  
  xmltable  
  (  
  	xmlnamespaces(default 'http://zakupki.gov.ru/oos/export/1','http://zakupki.gov.ru/oos/types/1' as "oos"),  
  	'/export/nsiOKPDList/nsiOKPD'  
  	passing xml_data  
  	columns  
      id number path 'oos:id',  
      parent_id number path 'oos:parentId',  
      code VARCHAR2(1000 CHAR) path 'oos:code',  
      parent_code VARCHAR2(1000 CHAR) path 'oos:parentCode',  
      name VARCHAR2(1000 CHAR) path 'oos:name',  
      description VARCHAR2(4000 CHAR) path 'oos:comment',  
      actual VARCHAR2(100 CHAR) path 'oos:actual'  
  ) R;
Результат:

[attachment 30084 R.png]



Исправлено: ВладимирС, 27.09.18 07:04
Ratings: 0 negative/0 positive


Вложения:
[R.png (4.7KB)]  



Извините, только зарегистрированные пользователи могут писать в этом форуме.

On-line: 54 and Guests: 54


© 2000-2018 Fox Club 
Яндекс.Метрика