2013-04-12 37 views
5

Tôi đang cố gắng để có được một đại diện nhỏ gọn về các không gian tên trong ElementTree hoặc lxml khi các phần tử phụ nằm trong một không gian tên khác với tên cha mẹ. Dưới đây là ví dụ cơ bản:Các Elementtree hoặc lxml nhỏ gọn hơn

from lxml import etree 

country = etree.Element("country") 

name = etree.SubElement(country, "{urn:test}name") 
name.text = "Canada" 
population = etree.SubElement(country, "{urn:test}population") 
population.text = "34M" 
etree.register_namespace('tst', 'urn:test') 

print(etree.tostring(country, pretty_print=True)) 

Tôi cũng đã cố gắng tiếp cận này:

ns = {"test" : "urn:test"} 

country = etree.Element("country", nsmap=ns) 

name = etree.SubElement(country, "{test}name") 
name.text = "Canada" 
population = etree.SubElement(country, "{test}population") 
population.text = "34M" 

print(etree.tostring(country, pretty_print=True)) 

Trong cả hai trường hợp, tôi nhận được một cái gì đó như thế này ra:

<country> 
    <ns0:name xmlns:ns0="urn:test">Canada</ns0:name> 
    <ns1:population xmlns:ns1="urn:test">34M</ns1:population> 
</country> 

Trong khi đó là chính xác, tôi muốn nó ít tiết hơn - điều này có thể trở thành vấn đề thực sự với các tập dữ liệu lớn (và đặc biệt là vì tôi đang sử dụng NS lớn hơn nhiều so với 'urn: test').

Nếu tôi OK với 'nước' là bên trong "urn: test" không gian tên và tuyên bố nó như vậy (trong ví dụ đầu tiên ở trên):

country = etree.Element("{test}country") 

sau đó tôi nhận được kết quả như sau:

<ns0:country xmlns:ns0="urn:test"> 
    <ns0:name>Canada</ns0:name> 
    <ns0:population>34M</ns0:population> 
</ns0:country> 

Nhưng những gì tôi thực sự muốn điều này là:

<country xmlns:ns0="urn:test"> 
    <ns0:name>Canada</ns0:name> 
    <ns0:population>34M</ns0:population> 
<country> 

Bất kỳ ý tưởng?

Trả lời

1
from xml.etree import cElementTree as ET 
##ET.register_namespace('tst', 'urn:test') 
country = ET.Element("country") 
name = ET.SubElement(country, "{urn:test}name") 
name.text = "Canada" 
population = ET.SubElement(country, "{urn:test}population") 
population.text = "34M" 
print prettify(country) 

trên sẽ cung cấp cho (mà không cần đăng ký bất kỳ không gian tên):

<?xml version="1.0" ?> 
<country xmlns:ns0="urn:test"> 
    <ns0:name>Canada</ns0:name> 
    <ns0:population>34M</ns0:population> 
</country> 

Và, khi tôi đã gỡ bỏ phần nhận xét nó sẽ cho ::

<?xml version="1.0" ?> 
<country xmlns:tst="urn:test"> 
    <tst:name>Canada</tst:name> 
    <tst:population>34M</tst:population> 
</country> 

lưu ý: prettify chức năng là here

+0

Cảm ơn! Điều này làm việc cho tôi. –

1

Mã này:

from lxml import etree 

ns = {"ns0" : "urn:test"} 
country = etree.Element("country", nsmap=ns) 

name = etree.SubElement(country, "{urn:test}name") 
name.text = "Canada" 

population = etree.SubElement(country, "{urn:test}population") 
population.text = "34M" 

print(etree.tostring(country, pretty_print=True)) 

dường như cung cấp đầu ra yêu cầu:

<country xmlns:ns0="urn:test"> 
    <ns0:name>Canada</ns0:name> 
    <ns0:population>34M</ns0:population> 
</country> 

nhưng bạn vẫn cần phải duy trì nsmap mình.

2
  1. tên đầy đủ của một phần tử chứa của {namespace-url}elementName, không {prefix}elementName

    >>> from lxml import etree as ET 
    >>> r = ET.Element('root', nsmap={'tst': 'urn:test'}) 
    >>> ET.SubElement(r, "{urn:test}child") 
    <Element {urn:test}child at 0x2592a80> 
    >>> ET.tostring(r) 
    '<root xmlns:tst="urn:test"><tst:child/></root>' 
    
  2. Trong trường hợp của bạn, thậm chí nhỏ gọn hơn đại diện có thể là nếu bạn cập nhật không gian tên mặc định. Unfortunatelly, lxml dường như không cho phép không gian tên XML trống rỗng, nhưng bạn nói, bạn có thể đặt thẻ mẹ vào không gian tên tương tự như phần tử con, vì vậy bạn có thể thiết lập không gian tên dafault vào đó yếu tố con:

    >>> r = ET.Element('{urn:test}root', nsmap={None: 'urn:test'}) 
    >>> ET.SubElement(r, "{urn:test}child") 
    <Element {urn:test}child at 0x2592b20> 
    >>> ET.SubElement(r, "{urn:test}child") 
    <Element {urn:test}child at 0x25928f0> 
    >>> ET.tostring(r) 
    '<root xmlns="urn:test"><child/><child/></root>' 
    
Các vấn đề liên quan