6

2 日前、私は初めて Python (およびプログラミング全般) を紹介されました。今日、私は立ち往生しています。私は非常に些細な問題であると思われる問題に対する答えを見つけるのに何時間も費やしました.他の誰もまだここで立ち往生していません:)

上司は、巨大な .xml ファイルを手動でクリーンアップして、より人間が読めるようにすることを望んでいます。私はそれを行うスクリプトを作成しようとしています。以下は、.xml ファイルと目的の出力の例です。

入力 (File.xml):

<IssueTracking>
  <Issue>
    <SequenceNum>123</SequenceNum>
    <Subject>Subject of Ticket 123</Subject>
    <Description>Line 1 in Description field of Ticket 123.
Line 2 in Description field of Ticket 123.
Line 3 in Description field of Ticket 123.</Description>
  </Issue>
  <Issue>
    <SequenceNum>124</SequenceNum>
    <Subject>Subject of Ticket 124</Subject>
    <Description>Line 1 in Description field of Ticket 124.
Line 2 in Description field of Ticket 124.
Line 3 in Description field of Ticket 124.</Description>
  </Issue>
</IssueTracking>

望ましい出力:

123    Subject of Ticket 123
Line 1 in Description field of Ticket 123.
Line 2 in Description field of Ticket 123.
Line 3 in Description field of Ticket 123.

124    Subject of Ticket 124
Line 1 in Description field of Ticket 124.
Line 2 in Description field of Ticket 124.
Line 3 in Description field of Ticket 124.

これが私がこれまでに得たものです。

with open(File.xml, 'r') as SourceFile: # Opens the file
    while 1: # Keep going through the file to the end
        SourceFileLine = SourceFile.readline() # Saves lines of the source file
        if not SourceFileLine: # Skip empty lines
            break

        SourceFileLine = SourceFileLine.strip() # Strips the whitespace

        if "<SequenceNum>" in SourceFileLine:
            SequenceNum = SourceFileLine[13:-14]  # Trims the tags, saves the field.
            continue

        if "<Subject>" in SourceFileLine:
            Subject = SourceFileLine[9:-10]
            continue

        #if "<Description>" in SourceFileLine:
        #    last_pos = SourceFile.tell() 
        #    while "</Description>" not in SourceFileLine:
        #        SourceFile.seek(last_pos)
        #        ?????
        #    
        #    Description = Description[22:]
        #    continue

        if "</Issue>" in SourceFileLine:
            print(SequenceNum, end = "\t")
            print(Subject)
        #    print(Description)
            print("\n")

<Description>タグ間のこれらの 3 行を識別して、ソース ファイルを読み進める前に印刷できる単一の文字列に保持することに行き詰まっています。ファイル行の読み取りループの他の多くの例をスキャンした結果、目的のフィールドに到達したポイントにフラグを立て、ファイル内のそのポイントに別の読み取りループをネストする必要があると思われます。しかし、これが行われている別の例を見つけていないので、基本的なものが欠けているか、より良い方法があると思います。助けてくれてありがとう!

4

2 に答える 2

7

データを処理するために強くお勧めする lxml の使用例。(注意: Py2.x 用に書かれていますが、Py3.x にも簡単に適応できます)

from lxml import etree
xml = """<IssueTracking>
  <Issue>
    <SequenceNum>123</SequenceNum>
    <Subject>Subject of Ticket 123</Subject>
    <Description>Line 1 in Description field of Ticket 123.
Line 2 in Description field of Ticket 123.
Line 3 in Description field of Ticket 123.</Description>
  </Issue>
  <Issue>
    <SequenceNum>124</SequenceNum>
    <Subject>Subject of Ticket 124</Subject>
    <Description>Line 1 in Description field of Ticket 124.
Line 2 in Description field of Ticket 124.
Line 3 in Description field of Ticket 124.</Description>
  </Issue>
</IssueTracking>
"""

root = etree.fromstring(xml)
for issue in root.findall('Issue'):
    as_list = [issue.find(n).text for n in ('SequenceNum', 'Subject', 'Description')]
    as_list[2] = as_list[2].split('\n')
    print as_list

版画:

['123', 'Subject of Ticket 123', ['Line 1 in Description field of Ticket 123.', 'Line 2 in Description field of Ticket 123.', 'Line 3 in Description field of Ticket 123.']]
['124', 'Subject of Ticket 124', ['Line 1 in Description field of Ticket 124.', 'Line 2 in Description field of Ticket 124.', 'Line 3 in Description field of Ticket 124.']]
于 2012-07-20T19:52:25.977 に答える
6

このような XML ファイルを読み取らないでください。python には、XML ファイルの読み取りを支援するさまざまなライブラリがあります。

Python ライブラリを見てください。lxmlこれは、XML ファイルを読み取って解析するための非常に簡単な方法を提供し、コードを大幅に改善します。

ライブラリ自体の使用方法を説明しますが、ドキュメントはこのテキスト領域に詰め込むよりもはるかに優れています: http://lxml.de/tutorial.html

于 2012-07-20T19:24:20.240 に答える