Разбор HTML таблицы с Oracle - PullRequest
       3

Разбор HTML таблицы с Oracle

0 голосов
/ 24 сентября 2019

Мне нужно разобрать таблицу HTML:

<table>
  <tbody>
    <tr class="blue"><td>code</td><td>rate</td></tr>
    <tr class="gray_1"><td><span>USD</span><em>1</em></td><td>476.16</td></tr>
    <tr class="gray_2"><td><span>AUD</span><em>1</em></td><td>327.65</td></tr>
    <tr class="gray_9"><td><span>IRR</span><em>100</em></td><td>1.13</td></tr>
    <tr class="blue"><td>some comment</td><td>some comment</td></tr>
    <tr class="gray_1"><td><span>EUR</span><em>1</em></td><td>526.54</td></tr>
  </tbody>
</table>

и в результате получить:

+------+----+----+------+
|class |code|em  |value |
+------+----+----+------+
|gray_1|USD |   1| 11.11|
|gray_2|AUD |   1| 22.22|
|gray_9|IRR | 100| 33.33|
|gray_1|EUR |   1| 44.44|

Я пытался сделать это так:

with tbl as
(
    select xmltype('
        <table>
          <tbody>
            <tr class="blue"><td>code</td><td>rate</td></tr>
            <tr class="gray_1"><td><span>USD</span><em>1</em></td><td>476.16</td></tr>
            <tr class="gray_2"><td><span>AUD</span><em>1</em></td><td>327.65</td></tr>
            <tr class="gray_9"><td><span>IRR</span><em>100</em></td><td>1.13</td></tr>
            <tr class="blue"><td>some comment</td><td>some comment</td></tr>
            <tr class="gray_1"><td><span>EUR</span><em>1</em></td><td>526.54</td></tr>
          </tbody>
        </table>
    ') xml_data from dual
)
select
    *
from
    tbl,
    xmltable('//table/tbody/tr'
        passing tbl.xml_data
        columns
            data varchar2(128) path './td'
    )

Но это вызывает исключение:

ORA-19279: XPTY0004 - Несоответствие динамического типа XQuery: ожидаемая одноэлементная последовательность - получена многоэлементная последовательность

Что янужно сделать, чтобы исправить мой код?

1 Ответ

2 голосов
/ 24 сентября 2019

Ваш path ищет td под tr;но есть два, следовательно, вы видите ошибку «есть последовательность из нескольких элементов».Вы можете ссылаться на каждый тег td по его позиции, как td[1] и т. Д. Он очень зависит от структуры таблицы, как и ожидалось.

С этим конкретным примером вы можете сделать:

with tbl as
(
    select xmltype('
        <table>
          <tbody>
            <tr class="blue"><td>code</td><td>rate</td></tr>
            <tr class="gray_1"><td><span>USD</span><em>1</em></td><td>476.16</td></tr>
            <tr class="gray_2"><td><span>AUD</span><em>1</em></td><td>327.65</td></tr>
            <tr class="gray_9"><td><span>IRR</span><em>100</em></td><td>1.13</td></tr>
            <tr class="blue"><td>some comment</td><td>some comment</td></tr>
            <tr class="gray_1"><td><span>EUR</span><em>1</em></td><td>526.54</td></tr>
          </tbody>
        </table>
    ') xml_data from dual
)
select
    x.class, x.currency, x.amount, to_number(x.rate) as rate
from
    tbl
cross join
    xmltable('/table/tbody/tr'
        passing tbl.xml_data
        columns
            class varchar2(10) path '@class',
            currency varchar2(3) path 'td[1]/span',
            amount number path 'td[1]/em',
            rate varchar2(50) path 'td[2]'
    ) x
where
    x.currency is not null

, который получает:

CLASS      CUR     AMOUNT       RATE
---------- --- ---------- ----------
gray_1     USD          1     476.16
gray_2     AUD          1     327.65
gray_9     IRR        100       1.13
gray_1     EUR          1     526.54

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...