0

QLineEdit フィールドと checkBox の状態をすべて読み取り、Minidom を使用して XML ファイルに保存しようとしています。以下は私がこれまでに持っているものです。for ループを使用してこれを記述する最も簡単で最短の方法は何ですか?

from xml.dom.minidom import Document

# Get all lineEdit values
mac = str(self.lineEdit_mac.text())
broadcast = str(self.lineEdit_broadcast.text())
destination = str(self.lineEdit_destination.text())
port = str(self.lineEdit_port.text())
destinationCheckBox=str(self.checkBox_destination.checkState())
portCheckBox=str(self.checkBox_port.checkState())

# Create the minidom document
doc = Document()

# Create the <wol> base element
wol = doc.createElement("wol")
doc.appendChild(wol)

# Create the <mac> node
node = doc.createElement("mac")
wol.appendChild(node)

# Give the <mac> element some text
nodeText = doc.createTextNode(mac)
node.appendChild(nodeText)

# Create the <broadcast> node
node = doc.createElement("broadcast")
wol.appendChild(node)

# Give the <broadcast> element some text
nodeText = doc.createTextNode(broadcast)
node.appendChild(nodeText)

# Create the <broadcast> node
node = doc.createElement("destination")
wol.appendChild(node)

# Give the <broadcast> element some text
nodeText = doc.createTextNode(destination)
node.appendChild(nodeText)

# Create the <port> node
node = doc.createElement("port")
wol.appendChild(node)

# Give the <port> element some text
nodeText = doc.createTextNode(port)
node.appendChild(nodeText)

# Create the <port> node
node = doc.createElement("destinationCheckBox")
wol.appendChild(node)

# Give the <port> element some text
nodeText = doc.createTextNode(destinationCheckBox)
node.appendChild(nodeText)

# Create the <port> node
node = doc.createElement("portCheckBox")
wol.appendChild(node)

# Give the <port> element some text
nodeText = doc.createTextNode(portCheckBox)
node.appendChild(nodeText)

# Write to document
f = open(fileName, 'w')
doc.writexml(f, indent='',addindent='  ',newl='\n')
f.closed

XML 出力:

<?xml version="1.0" ?>
<wol>
  <mac>
    00:00:00:00:00:00
  </mac>
  <broadcast>
    192.168.1.255
  </broadcast>
  <destination>

  </destination>
  <port>
    9
  </port>
  <destinationCheckBox>
    0
  </destinationCheckBox>
  <portCheckBox>
    0
  </portCheckBox>
</wol>

また、xml を次のようにフォーマットする最も簡単な方法は何ですか?

<?xml version="1.0" ?>
<wol>
  <mac>00:00:00:00:00:00</mac>
  <broadcast>192.168.1.255</broadcast>
  <destination></destination>
  <port>9</port>
  <destinationCheckBox>0</destinationCheckBox>
  <portCheckBox>0</portCheckBox>
</wol>
4

1 に答える 1

0

次のようなことを試すことができます:

from xml.dom.minidom import Document

# Get all lineEdit values
elements = dict(
    mac = self.lineEdit_mac.text,
    broadcast = self.lineEdit_broadcast.text,
    destination = self.lineEdit_destination.text,
    port = self.lineEdit_port.text,
    destinationCheckBox = self.checkBox_destination.checkState,
    portCheckBox = self.checkBox_port.checkState
)

doc = Document()
wol = doc.createElement("wol")
doc.appendChild(wol)

for name, fn in elements.iteritems():
    node = doc.createElement(name)
    wol.appendChild(node)

    text = str(fn())
    nodeText = doc.createTextNode(text)
    node.appendChild(nodeText)

with open(fileName, 'w') as f:
    doc.writexml(f, indent='', addindent='  ', newl='\n')

関数を実際のテキスト値ではなく dict 値として配置することを提案した理由は、この要素 dict を後の段階で xml プロセスの構成オブジェクトとして使用できるためです。次に、含めるためにdictに別の要素を追加するだけです。

xml 出力の再フォーマットに関しては、現在の方法は、組み込みのプリティ プリンターの動作方法です。テキスト ノードは別のタイプの子ノードにすぎないため、新しいインデントされた行を使用します。DOM を手動でループし、必要な方法で印刷する独自のきれいなプリンター機能を実行する必要があります (テキスト型ノードをチェックし、同じ行に印刷します)。

特に XML に縛られていない場合に備えて、必要に応じて JSON を使用してこれをさらに短縮できます。

import json

elements = dict(
    mac = self.lineEdit_mac.text,
    broadcast = self.lineEdit_broadcast.text,
    destination = self.lineEdit_destination.text,
    port = self.lineEdit_port.text,
    destinationCheckBox = self.checkBox_destination.checkState,
    portCheckBox = self.checkBox_port.checkState
)

with open(fileName, 'w') as f:
    # if you need the root key
    data = {'wol': dict((name, str(fn())) for name, fn in elements.iteritems())}
    json.dump(data, f, indent=4)

    # or, just the key/values
    #json.dump(elements, f, indent=4, default=lambda o: str(o()))

要素の順序が重要な場合

辞書を使用すると、元のエントリの順序が維持されません。何らかの理由でこれが重要な場合は、タプルを使用できます。

elements = (
    ('mac', self.lineEdit_mac.text),
    ('broadcast', self.lineEdit_broadcast.text),
    ('destination', self.lineEdit_destination.text),
    ('port', self.lineEdit_port.text),
    ('destinationCheckBox', self.checkBox_destination.checkState),
    ('portCheckBox', self.checkBox_port.checkState)
)

# and remove .iteritems() where previously used
for name, fn in elements:

または、python2.7 を使用している場合 (または古いバージョンにバックポートされたバージョンをダウンロードしている場合)、OrderedDictを使用できます。

于 2012-04-08T22:35:04.317 に答える