2010-09-10 77 views
3

我正在嘗試使用lxml創建XML模式。對於的遊戲內是這樣的:如何使用lxml在屬性值中設置命名空間前綴?

<xs:schema xmlns="http://www.goo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema"   elementFormDefault="qualified" targetNamespace="http://www.goo.com"> 
    <xs:element type="xs:string" name="name"/> 
    <xs:element type="xs:positiveInteger" name="age"/> 
</xs:schema> 

我已經做到了這種方式 - 通過putthing XS:前值,但我認爲這是可以做到更好。

def schema(): 
    SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema" 
    XS = "{%s}" % SCHEMA_NAMESPACE 
    NSMAP = {None: "http://www.goo.com"} 

    schema = etree.Element(XS+"schema", 
          nsmap = NSMAP, 
          targetNamespace="http://www.goo.com", 
          elementFormDefault="qualified") 

    element = etree.Element(XS+"element", 
          attrib = {"name" : "name", 
             "type" : "xs:string"}) 
    schema.append(element) 
    element = etree.Element(XS+"element", 
          attrib = {"name" : "age", 
             "type" : "xs:positiveInteger"}) 

    schema.append(element) 
    return etree.tostring(schema, pretty_print=True) 

它可以以某種方式寫得更好嗎?

回答

2

有點值得一提,你需要在你的NSMAP中包含"xs": SCHEMA_NAMESPACE等,否則在你生成的XML中沒有任何東西實際將'xs'前綴映射到正確的名稱空間。這也可以讓你只用前綴指定你的元素名稱;例如「XS:元素」。

至於你的主要問題,我認爲這可能很好,只要你總是在任何地方使用相同的前綴到名稱空間映射,比如全局的NSMAP。如果你正在處理XML具有潛在的任意命名空間前綴,然後確保要麼:

  • 與「XS」前綴創建的每一個元素添加您的nsmap;或
  • 使用_Element.nsmap屬性獲取父屬性的名稱空間映射,將其反轉,並在倒轉映射中查找適當的前綴。

後者的一個例子:

SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema" 

def add_element(schema): 
    nsmap = schema.nsmap 
    nsrmap = dict([(uri, prefix) for prefix, uri in nsmap.items()]) 
    prefix = nsrmap[SCHEMA_NAMESPACE] 
    xs = lambda name: "%s:%s" % (prefix, name) 
    element = schema.makeelement(xs("element"), nsmap=nsmap, 
           attrib={'name': 'age', 'type': xs('string')}) 
    schema.append(element) 
    return etree.tostring(schema, pretty_print=True) 

但是,這可能是大多數情況下矯枉過正。

相關問題