2011-02-03 97 views
4

我想檢索一個遺留的xml文件,操作並保存它。Python:XML中的命名空間ElementTree(或lxml)

這裏是我的代碼:

from xml.etree import cElementTree as ET 
NS = "{http://www.somedomain.com/XI/Traffic/10}" 

def fix_xml(filename): 
    f = ET.parse(filename) 
    root = f.getroot() 
    eventlist = root.findall("%(ns)Event" % {'ns':NS }) 
    xpath = "%(ns)sEventDetail/%(ns)sEventDescription" % {'ns':NS } 
    for event in eventlist: 
     desc = event.find(xpath) 
     desc.text = desc.text.upper() # do some editting to the text. 

    ET.ElementTree(root, nsmap=NS).write("out.xml", encoding="utf-8") 


shorten_xml("test.xml") 

文件I負載包括:

xmlns="http://www.somedomain.com/XI/Traffic/10" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.somedomain.com/XI/Traffic/10 10.xds" 

在根標籤。

我有以下問題,涉及到的命名空間:

  • 正如你看到的,對於每一個標籤調用,我給在開始時的命名空間中檢索一個孩子。
  • 生成的xml文件在開始時沒有<?xml version="1.0" encoding="utf-8"?>
  • 輸出端的標籤包含這樣的<ns0:eventDescription>,而我需要的輸出爲原始的<eventDescription>,沒有命名空間開頭。

這些如何解決?

回答

4

看看lxml tutorial section on namespaces。這也是article about namespaces in ElementTree

問題1:像其他人一樣忍受它。而不是"%(ns)Event" % {'ns':NS }嘗試NS+"Event"

問題2:默認情況下,只有在需要時才寫入XML聲明。您可以在write()調用中使用xml_declaration=True強制執行(僅限lxml)。

問題3:nsmap arg似乎僅爲lxml-only。 AFAICT它需要一個MAPPING,而不是一個字符串。嘗試nsmap={None: NS}。該effbot文章有一節描述瞭解決這個問題的方法。

1

回答您的問題依次是:

  • 你不能忽略的命名空間,而不是在路徑語法.findall()用途,而不是在「真實」的XPath(按LXML支持)之一:那裏你仍然被迫使用前綴,並且仍然需要提供一些前綴到URI的映射。

  • 使用xml_declaration=True以及encoding='utf-8'.write()調用(在LXML可用,但只因爲Python 2.7,我相信STDLIB xml.etree)

  • 相信LXML會做的行爲像你想

相關問題