Разобрать строку XML в MySQL - PullRequest
7 голосов
/ 24 мая 2009

У меня есть задача анализа простой строки в формате XML в хранимой процедуре MySQL. XML выглядит следующим образом (только для целей тестирования):

<parent>
    <child>Example 1</child>
    <child>Example 2</child>
</parent>

Что мне нужно, чтобы MySQL - это выводить набор результатов по одной строке на совпадение. Мой сохраненный код процедуры выглядит так:

DECLARE xmlDoc TEXT;
SET xmlDoc = '<parent><child>Example 1</child><child>Example 2</child></parent>';
SELECT ExtractValue(xmlDoc, '//child');

Однако он объединяет все совпадения и выдает «Пример 1, Пример 2». Это, кстати, задокументированное, но совершенно бесполезное поведение.

Что я могу сделать, чтобы он возвращал совпадения в строках , не считая совпадения и не обрабатывая их один за другим? Возможно ли это даже с MySQL?

Спасибо всем!

Ответы [ 3 ]

8 голосов
/ 24 мая 2009

Для этого требуется функция генерации набора строк, а MySQL - в ней нет.

Вместо этого вы можете использовать фиктивную таблицу или подзапрос:

SELECT  ExtractValue(@xml, '//mychild[$@r]'),
        @r := @r + 1
FROM    (
        SELECT  @r := 1
        UNION ALL
        SELECT  1
        ) vars

Обратите внимание, что поддержка переменных сеанса в XPath нарушена в 5.2 (но отлично работает в 5.1)

7 голосов
/ 24 мая 2009
DECLARE i INT DEFAULT 1;
DECLARE count DEFAULT ExtractValue(xml, 'count(//child)');

WHILE i <= count DO
    SELECT ExtractValue(xml, '//child[$i]');
    SET i = i+1;
END WHILE

Другой способ ...

DECLARE v VARCHAR(500) DEFAULT '';
DECLARE i INT DEFAULT 1;

REPEAT
    SET v = ExtractValue(xml, '//child[$i]')
    SET i = i+1;
    IF v IS NOT NULL THEN
        -- do something with v
    END IF
UNTIL v IS NULL

Извините, если здесь синтаксис немного шаткий, не так много для гуру mysql ...

1 голос
/ 26 сентября 2016

Ниже приведен пример хранимой процедуры для чтения xml с использованием цикла while

-- drop procedure testabk;
-- call testabk();
delimiter //
create procedure testabk()
begin

DECLARE k INT UNSIGNED DEFAULT 0;
DECLARE xpath TEXT;
declare doc varchar(1000);
DECLARE row_count1 INT UNSIGNED; 

set doc='<StaticAttributesBM><AttributeId id="11">Status</AttributeId><AttributeId id="2">Reason</AttributeId><AttributeId id="3">User Remarks</AttributeId></StaticAttributesBM>';
DROP TABLE IF EXISTS tempStaticKeywords;
CREATE TABLE tempStaticKeywords(id int, staticKeywords VARCHAR(500));
SET row_count1 := extractValue(doc,'count(/StaticAttributesBM/AttributeId)');
select row_count1;

-- iterate over books
WHILE k < row_count1 DO        
    SET k := k + 1;
    SET xpath := concat('/StaticAttributesBM/AttributeId[', k, ']');
    INSERT INTO tempStaticKeywords(id,staticKeywords) VALUES (
      extractValue(doc, concat(xpath,'/@id')),
      extractValue(doc, xpath)     
    );
END WHILE;

select * from tempStaticKeywords;

END
//

Выход ниже

id staticKeywords

1 Статус

2 Причина

3 Замечания пользователя

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