在MySQL中解析XML字符串

时间:2009-05-23 22:58:14

标签: mysql xml xpath

我的任务是在MySQL存储过程中解析一个简单的XML格式的字符串。 XML看起来像这样(仅用于测试目的):

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

我需要MySQL做的是每个匹配生成一行结果集。我存储的proc代码如下所示:

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

然而,这是连接所有匹配,产生“示例1示例2”。顺便说一下,这是有记录的,但却毫无用处。

如何让它返回行中的匹配,而不必计算匹配并逐个处理它们?甚至可以使用MySQL吗?

全部谢谢!

3 个答案:

答案 0 :(得分:8)

这需要一个行集生成函数,MySQL缺少它。

您可以使用虚拟表或子查询:

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

请注意,XPath中对会话变量的支持在5.2中已被破坏(但在5.1中正常工作)

答案 1 :(得分:7)

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大师......

答案 2 :(得分:1)

下面是使用while循环

读取xml的存储过程示例
-- 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用户备注