8

従来の xml ファイルを取得し、操作して保存したいと考えています。

これが私のコードです:

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

ロードするファイルには次が含まれます。

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

2 に答える 2

8

namespaces に関するlxmlチュートリアル セクションをご覧ください。ElementTree の名前空間に関するこの記事も参照してください。

問題 1: 他の人と同じように我慢する。"%(ns)Event" % {'ns':NS }試してみる代わりにNS+"Event"

問題 2: デフォルトでは、XML 宣言は必要な場合にのみ記述されます。xml_declaration=True呼び出しで使用して強制できます (lxml のみ) write()

問題 3:nsmap引数が lxml のみのようです。AFAICT 文字列ではなく MAPping が必要です。試してみてくださいnsmap={None: NS}。effbot の記事には、これに対する回避策を説明するセクションがあります。

于 2011-02-03T13:37:07.090 に答える
1

質問に順番に答えるには:

  • を使用するパス構文ではなく、名前空間を無視することはできませんが.findall()、「実際の」xpath(lxmlでサポートされています)でも無視できません。それでもプレフィックスを使用する必要があり、まだいくつかのプレフィックスを提供する必要があります-to-uri マッピング。

  • xml_declaration=True呼び出しと同様に使用encoding='utf-8'.write()ます(lxmlで利用できますが、stdlib xml.etreeでのみpython 2.7以降で利用できると思います)

  • lxml はあなたが望むように動作すると思います

于 2011-02-03T13:37:07.810 に答える