2010-11-09 14 views
1

我有一些XML如下:使用Python來從SQL表的XML

<dd> 
    <persson> 
     <name>sam</name> 
     <tel>9748</tel> 
    </persson> 
    <cat> 
     <name>frank</name> 
    </cat> 
</dd> 

我解析它分成兩個SQL表,一個標籤,一個是PCDATA。開始和停止列表示標籤出現和結束的位置。

Tags: 
start | stop | tag 
-------+------+-------- 
    3 | 5 | name 
    6 | 8 | tel 
    2 | 9 | persson 
    11 | 13 | name 
    10 | 14 | cat 
    1 | 15 | dd 
(6 rows) 

Pcdata: 
pos | pcdata 
-----+-------- 
    4 | sam 
    7 | 9748 
    12 | frank 
(3 rows) 

現在我想解析這個數據庫回到原始形式的XML。我想編寫一個函數,該函數使用兩個表並將XML寫入文件中。我使用python和psycopg2來做到這一點。

+0

OP發生了什麼事? – Danosaure 2010-11-10 15:43:37

+0

@Danosure:看起來他正在編輯他的問題,塞滿了它,並不知道如何解決它。我做了回滾。 – 2010-11-10 18:53:06

回答

3

H'mmm已經解碼的「列」:

<dd><persson><name>sam</name><tel>9748</tel></persson> 
1 2  3  4 5  6 7 8  9      
<cat><name>frank</name></cat></dd> 
10 11 12 13  14 15 

我對你有一些問題:你是怎麼做到的?你爲什麼這麼做?你究竟想要達到什麼目標?請注意,您的問題標題頗具誤導性 - 「SQL表格」僅僅是您停留數據的特殊表示的地方。

下面是一些僞代碼,做你想做的事:

pieces = [] 
result = cursor.execute("select * from tags;") 
for start, step, tag in result: 
    pieces.append((start, "<" + tag + ">")) 
    pieces.append((stop, "</" + tag + ">")) 
result = cursor.execute("select * from pcdata;") 
for pos, pcdata in result: 
    pieces.append((pos, pcdata)) 
pieces.sort() 
xml_stream = "".join(piece[1] for piece in pieces) 
your_file_object.write(xml_stream) 

在回答關於是否上面會放「位置」的輸出流中的問題:沒有也不會;以下片段顯示它的工作。這些職位僅用於將湯排序到正確的順序。在「加入」中,piece[0]是指該位置,但未使用,只有piece[1]這是必填文本。

>>> pieces 
[(3, '<name>'), (4, 'sam'), (5, '</name>')] 
>>> ''.join(piece[1] for piece in pieces) 
'<name>sam</name>' 

鬆口的SQL註釋的問題:

雖然所示使用SQLite,這是沼澤標準SQL。如果您的數據庫不支持||作爲級聯運算符,請嘗試+

問題,你忘了問:「我怎麼得到<?xml blah-blah ?> thingie在前面?」。答案:見下文。

console-prompt>sqlite3 
SQLite version 3.6.14 
Enter ".help" for instructions 
Enter SQL statements terminated with a ";" 
sqlite> create table tags (start int, stop int, tag text); 
sqlite> insert into tags values(3,5,'name'); 
sqlite> insert into tags values(6,8,'tel'); 
sqlite> insert into tags values(2,9,'persson'); 
sqlite> insert into tags values(11,13,'name'); 
sqlite> insert into tags values(10,14,'cat'); 
sqlite> insert into tags values(1,15,'dd'); 
sqlite> create table pcdata (pos int, pcdata text); 
sqlite> insert into pcdata values(4,'sam'); 
sqlite> insert into pcdata values(7,'9748'); 
sqlite> insert into pcdata values(12,'frank'); 
sqlite> select datum from (
    ...>  select 0 as posn, '<?xml version="1.0" encoding="UTF-8"?>' as datum 
    ...>  union 
    ...>  select start as posn, '<' || tag || '>' as datum from tags 
    ...>  union 
    ...>  select stop as posn, '</' || tag || '>' as datum from tags 
    ...>  union 
    ...>  select pos as posn, pcdata as datum from pcdata 
    ...> ) 
    ...> order by posn; 
<?xml version="1.0" encoding="UTF-8"?> 
<dd> 
<persson> 
<name> 
sam 
</name> 
<tel> 
9748 
</tel> 
</persson> 
<cat> 
<name> 
frank 
</name> 
</cat> 
</dd> 
sqlite> 
+0

是的,我編號的每個標籤的位置,並將其存儲在表中。這是我被要求代表數據的方式。 – Spawn 2010-11-10 00:27:26

+0

我現在該如何從數據庫表中重新生成XML? – Spawn 2010-11-10 00:27:50

+1

「我被問過」的方式是誰?老師?老闆?鏈鋸瘋子? – 2010-11-10 00:59:35

1

首先,如果Postgres的包括機制,爲創建XML時使用它們。

其次,除非你真的知道你在做什麼,否則不要使用字符串操作來創建XML。即使如此,不要。例如,如果任何列包含&符號,只需連接數據庫中的字符串值就會生成格式錯誤的XML。

除非您將處理太多的數據以適應內存,否則請使用John Machin的方法將數據解析爲元素,然後使用lxml.etree來創建實際的XML元素。