1. ホーム
  2. python

[解決済み] Python lxml tostring not print nsmap

2022-02-16 03:09:53

質問

Doxygen XMLパーサーで作業しています。私の問題は実は単純で、LXMLの tostring を使用して、XML 要素の生のコンテンツを取得します。

ETreeで動作させていましたが、LMXLに切り替えたので、以下のようになります。 strip_tags .

例えば、こんなXMLファイルがあるとします。

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.16">
  <child2/>
  <child3/>
</root>

そして、こうしています。

tree = ET.parse('new1.xml')
root = tree.getroot()
child3 = root.find("./child3")

objectify.deannotate(child3, cleanup_namespaces=True, xsi=True, pytype=True)
etree.cleanup_namespaces(child3)
child3.nsmap.clear()
etree.strip_attributes(child3, 'nsmap') 

print(ET.tostring(child3, encoding='unicode', pretty_print=True))

こんな感じです。

<child3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

これが私のWANTです。

<child3/>

への文字列を指定するオプションはありますか? NOT nsmapを印刷しますか?

試してみました。

試してみると

root.nsmap = None

例外が発生する

AttributeError: attribute 'nsmap' of 'lxml.etree._Element' objects is not writable

Python 3.7 64bitをWindows 10で使用しています。

ありがとうございました。

解決方法は?

XMLドキュメント内の http://www.w3.org/2001/XMLSchema 名前空間が使用されています。そのため xsi:noNamespaceSchemaLocation 属性はその名前空間に束縛されます。

目的の出力を得るためには、1)この関数から xsi:noNamespaceSchemaLocation 属性を削除し、2) 名前空間の宣言を削除します。

from lxml import etree

tree = etree.parse('new1.xml')
root = tree.getroot()

# Remove the xsi:noNamespaceSchemaLocation attribute
del root.attrib["{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation"]

# Remove the declaration for the now unused namespace. Must be done on the root element
etree.cleanup_namespaces(root)

child3 = root.find("./child3")

# Print child3
print(etree.tostring(child3, encoding='unicode', pretty_print=True))

# Print the whole document
print(etree.tostring(root, encoding='unicode', pretty_print=True))

出力します。

<child3/>


<root version="1.8.16">
  <child2/>
  <child3/>
</root>