3

解析したい XML ファイルのフォルダーがあります。これらのファイルの要素からテキストを取得する必要があります。それらは収集され、要素が列にリストされている CSV ファイルに出力されます。

一部のファイルに対して、実際にこれを今すぐ実行できます。つまり、私の XML ファイルの多くでは、プロセスはうまくいき、必要な出力が得られます。これを行うコードは次のとおりです。

import os, re, csv, string, operator
import xml.etree.cElementTree as ET
import codecs
def parseEO(doc):
    #getting the basic structure
    tree = ET.ElementTree(file=doc)
    root = tree.getroot()
    agencycodes = []
    rins = []
    titles =[]
    elements = [agencycodes, rins, titles]
    #pulling in the text from the fields
    for elem in tree.iter():
        if elem.tag == "AGENCY_CODE":
            agencycodes.append(int(elem.text))
        elif elem.tag == "RIN":
            rins.append(elem.text)
        elif elem.tag == "TITLE":
            titles.append(elem.text)
    with open('parsetest.csv', 'w') as f:
        writer = csv.writer(f)
        writer.writerows(zip(*elements))


parseEO('EO_file.xml')     

ただし、入力ファイルの一部のバージョンでは、悪名高いエラーが発生します。

'ascii' codec can't encode character u'\x97' in position 32: ordinal not in range(128)

完全なトレースバックは次のとおりです。

    ---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-15-28d095d44f02> in <module>()
----> 1 execfile(r'/parsingtest.py') # PYTHON-MODE

/Users/ian/Desktop/parsingtest.py in <module>()
     91         writer.writerows(zip(*elements))
     92 
---> 93 parseEO('/EO_file.xml')
     94 
     95 

/parsingtest.py in parseEO(doc)
     89     with open('parsetest.csv', 'w') as f:
     90         writer = csv.writer(f)
---> 91         writer.writerows(zip(*elements))
     92 
     93 parseEO('/EO_file.xml')
UnicodeEncodeError: 'ascii' codec can't encode character u'\x97' in position 32: ordinal not in range(128)

他のスレッドを読んで、問題が使用されているコーデックにあることはかなり確信しています (そして、ご存知のように、エラーはそれについてもかなり明確です)。しかし、私が読んだ解決策は私を助けませんでした(過去に人々が答えた方法ではなく、私が問題の原因であることを理解しているため、強調しました)。

いくつかの応答 (たとえば、this onethis onethis one ) は ElementTree を直接扱っていません。解決策を自分がしていることに変換する方法がわかりません。

ElementTree を扱う他のソリューション (例: this oneおよびthis one ) は、短い文字列 (ここの最初のリンク) を使用しているか、ElementTree で .tostring/.fromstring メソッドを使用していますが、私は使用していません。(もちろん、そうすべきかもしれませんが。)

私が試したことはうまくいきませんでした:

  1. UTF-8エンコーディングでファイルを取り込もうとしました:

    infile = codecs.open('/EO_file.xml', encoding="utf-8")
    parseEO(infile)
    

    しかし、ElementTree プロセスはすでにそれが UTF-8 であることを理解していると思います (これは、私が持っているすべての XML ファイルの最初の行に記載されています)。

  2. ループ内でエンコード プロセスを宣言しようとしました。

    tree = ET.ElementTree(file=doc)
    

    parser = ET.XMLParser(encoding="utf-8")
    tree = ET.parse(doc, parser=parser)
    

    上記のループでは機能します。これも私にはうまくいきませんでした。以前は機能していた同じファイルが引き続き機能し、エラーを作成した同じファイルが引き続きエラーを作成しました。

他にもたくさんのランダムな試みがありましたが、私は要点を詳しく説明しません.

したがって、私が持っているコードは非効率的であり、優れたプログラミング スタイルに不快感を与えるものだと思いますが、いくつかのファイルに対しては、私が望むことを実行します。ファイルを何らかの形で前処理する必要があるかどうか、私が知らない単純な引数があるかどうかを理解しようとしています (問題のある文字がどこにあるかは特定していませんが、u'\ x97 では、ある種の制御文字に変換されます)、またはその他のオプションに変換されます。

4

2 に答える 2

10

XML を解析しています。XML API が値を渡しますunicode。次に、Unicode データを最初にエンコードせずに CSV ファイルに書き込もうとしています。Python はそれをエンコードしようとしますが、失敗します。これはトレースバックで確認できます。失敗したのは.writerows()呼び出しであり、エラーはエンコードが失敗しており、デコード (XML の解析) ではないことを示しています。

エンコーディングを選択し、書き込む前にデータをエンコードする必要があります。

for elem in tree.iter():
    if elem.tag == "AGENCY_CODE":
        agencycodes.append(int(elem.text))
    elif elem.tag == "RIN":
        rins.append(elem.text.encode('utf8'))
    elif elem.tag == "TITLE":
        titles.append(elem.text.encode('utf8'))

Unicode コード ポイントを処理できる UTF8 エンコーディングを使用しましたが、独自の明示的な選択を行う必要があります。

于 2013-06-22T23:56:19.657 に答える
3

xml ファイルのどこかに Unicode 文字があるようです。Unicode は、utf8 でエンコードされた文字列とは異なります。

python2.7 csv ライブラリは Unicode 文字をサポートしていないため、csv ファイルにダンプする前に、それらをエンコードする関数を使用してデータを実行する必要があります。

def normalize(s):
    if type(s) == unicode: 
        return s.encode('utf8', 'ignore')
    else:
        return str(s)

コードは次のようになります。

for elem in tree.iter():
    if elem.tag == "AGENCY_CODE":
        agencycodes.append(int(elem.text))
    elif elem.tag == "RIN":
        rins.append(normalize(elem.text))
    elif elem.tag == "TITLE":
        titles.append(normalize(elem.text))
于 2013-06-23T00:14:19.400 に答える