2013-04-12 13 views
5

サブ要素が親と異なる名前空間にある場合、ElementTreeまたはlxmlに名前空間のコンパクトな表現を取得しようとしています。私は、コンパクトElementTreeまたはlxml名前空間

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

それは正しいですが:私もこのアプローチを試みた

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)) 

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)) 

両方のケースでは、私はこのような何かを出すここで基本的な例でありますこれはあまり冗長ではないと思いますが、これは大きなデータセットでは本当の問題になる可能性があります(特に私が 'urn:test'よりもはるかに大きなNSを使用しているため)。

私は「国」は「URN:テスト」の内側にあることでOKだ場合は、名前空間と(上記の最初の例では)ので、同じようにそれを宣言します。

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

その後、私は次のような出力が得られます。

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

しかし、私が本当にしたいことはこれです:

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

任意のアイデア?

答えて

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) 

(任意の名前空間を登録せずに)与える:私はコメント部分を削除したときに得られます::

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

ノート、

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

そして:prettify関数であるがhere

+0

ありがとう!これは私のために働いた。 –

1

このコード:

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)) 

は、必要な出力を提供するようだ:

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

をあなたはまだnsmapを自分で維持する必要があります。上記

2
  1. 要素の完全な名前は、デフォルトの名前空間を更新した場合でも、よりコンパクトな表現があるかもしれない、あなたのケースではない{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. {namespace-url}elementNameの含まれています。生憎、lxmlは空のXML名前空間を許可していないようですが、あなたは、あなたが子要素と同じ名前空間に親タグを置くことができる、と言うので、あなたは、子要素のそれにdafault名前空間を設定することができます。

    >>> 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>' 
    
関連する問題