質問

ElementTreeとxpathを使用してxmlファイル内の特定の要素のテキストコンテンツを抽出する小さな関数を作成しました:

#!/usr/bin/env python2.5

import doctest
from xml.etree import ElementTree
from StringIO import StringIO

def parse_xml_etree(sin, xpath):
  """
Takes as input a stream containing XML and an XPath expression.
Applies the XPath expression to the XML and returns a generator
yielding the text contents of each element returned.

>>> parse_xml_etree(
...   StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
...   '//elem1').next()
'one'
>>> parse_xml_etree(
...   StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
...   '//elem2').next()
'two'
>>> parse_xml_etree(
...   StringIO('<test><null>&#0;</null><elem3>three</elem3></test>'),
...   '//elem2').next()
'three'
"""

  tree = ElementTree.parse(sin)
  for element in tree.findall(xpath):
    yield element.text  

if __name__ == '__main__':
  doctest.testmod(verbose=True)

第三のテストは、次の例外で失敗します:

エクスパターラー:無効な文字番号への参照:1行目13列目

は、 &#0; エンティティ不正なXML?それがあるかどうかにかかわらず、解析したいファイルにはそれが含まれており、それらを解析する方法が必要です。Expat以外の別のパーサーの提案、またはExpatの設定は、私がそれを行うことを可能にするでしょうか?


更新:私は発見しました ビューティフルソープ ちょうど今、答えのコメントで以下に記載されているタグスープパーサー、そして楽しみのために私はこの問題に戻り、ElementTreeの前でXMLクリーナーとして使用しようとしましたが、それは忠実に変換されました &#0; 無効なヌルバイトと同じように入力します。:-)

cleaned_s = StringIO(
  BeautifulStoneSoup('<test><null>&#0;</null><elem3>three</elem3></test>',
                     convertEntities=BeautifulStoneSoup.XML_ENTITIES
  ).renderContents()
)
tree = ElementTree.parse(cleaned_s)

...歩留まり

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12

しかし、私の特定のケースでは、私は本当にそのようなXPath解析を必要としませんでした、私はBeautifulSoup自体とその非常に単純なノードadressingスタイルで行っている可能性 parsed_tree.test.elem1.contents[0].

役に立ちましたか?

解決

&#0; ではありません 法定文字範囲 XML仕様によって定義されます。悲しいかな、私のPythonのスキルはかなり初歩的なものなので、私はそこではあまり助けになりません。

他のヒント

&#0;は有効なXML文字ではありません。理想的には、ファイルの作成者にプロセスを変更してもらい、ファイルがこのように無効にならないようにすることができます。

これらのファイルを受け入れる必要がある場合は、それらを前処理して、&#0を別のものに変えることができます。たとえば、エスケープ文字として@を選択し、「@」を「@@」に、「&#0;」を「@ 0」に変換します。

次に、パーサーからテキストデータを取得すると、マッピングを逆にすることができます。これは単なる例であり、任意のエスケープ構文を考案できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top