我的任务是在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吗?
全部谢谢!
答案 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用户备注