2009-05-23 50 views
7

Tôi có một nhiệm vụ phân tích một chuỗi được định dạng XML đơn giản trong một thủ tục được lưu trữ MySQL. XML trông giống như thế này (chỉ dành cho mục đích thử nghiệm):Phân tích cú pháp một chuỗi XML trong MySQL

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

Điều tôi cần làm là tạo ra một tập hợp kết quả mỗi hàng. đang proc lưu trữ của tôi trông như thế này:

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

Điều này không, tuy nhiên, là nó nối tất cả các trận đấu, sản xuất "Ví dụ 1 Ví dụ 2". Đây là, bằng cách này, tài liệu, nhưng hành vi khá vô dụng.

Tôi có thể làm gì để làm cho nó trả về các kết quả phù hợp trong các hàng mà không cần phải đếm các kết quả phù hợp và xử lý chúng từng cái một? Nó có khả thi với MySQL không?

Cảm ơn tất cả!

Trả lời

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 

Ngoài ra ...

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 

Xin lỗi nếu cú ​​pháp là một chút Shakey ở đây, không nhiều của một guru mysql ...

8

này cần một chức năng thế hệ rowset, và MySQL thiếu nó.

Bạn có thể sử dụng một bảng giả hoặc một subquery thay vì:

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

Lưu ý rằng hỗ trợ cho các biến session trong XPath bị phá vỡ trong 5.2 (nhưng hoạt động tốt trong 5.1)

+0

này hoạt động khá tốt. Cảm ơn. –

+0

Sử dụng truy vấn này, tôi chỉ nhận được hai hàng. Tui bỏ lỡ điều gì vậy? – reticent

+0

@reticent: như đã nói trước đây, 'MySQL' thiếu một hàm tạo hàng. Truy vấn con chỉ trả về 2 hàng mà bạn nhận được. Thêm nhiều hàng vào 'vars' (hoặc thay thế nó bằng' SELECT' từ một bảng đủ lớn). – Quassnoi

1

Dưới đây là một thủ tục lưu trữ ví dụ để đọc xml sử dụng vòng lặp 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 
// 

Đầu ra dưới

id staticKeywords

1 Status

2 Lý do

3 User Bình luận