解析MySQL中的XML字符串
问题描述:
我有一个解析MySQL存储过程中简单的XML格式的字符串的任务。 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甚至有可能吗?
谢谢大家!
答
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的大师......
答
这需要一个行集生成功能,以及MySQL
缺乏它。
您可以使用一个虚拟表或子查询,而不是:
SELECT ExtractValue(@xml, '//mychild[[email protected]]'),
@r := @r + 1
FROM (
SELECT @r := 1
UNION ALL
SELECT 1
) vars
注意会话变量XPath
在5.2
被打破,支持(但5.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用户备注
这工作相当好。谢谢。 – 2009-05-25 01:37:18