0

私はこのようなxmlファイルを持っています:

<data>
      <entry>
           <word>ABC</word> (this)
      </entry>
      <entry>
           <word>ABC</word> [not this]
      </entry>
</data>

子孫に「(」が含まれているノードを選択し、(。*)をのテキストに移動したい<entry>。つまり:

<data>
      <entry>
           (this)
           <word>ABC</word>
      </entry>
      <entry>
           <word>ABC</word> [not this]
      </entry>
</data>

私はlxmlを使用しています。そして私は試しました:

 import lxml.etree as ET
 data = ET.parse('sample.xml')
 for entry in data.iter('entry'):
      A = entry.xpath('.//*[text() = ".*(.*?)"]')

しかし、それは機能しません。「(」は、ノードの末尾またはノードのテキストとして表示できます。

4

2 に答える 2

0

尻尾にある場合(は、それを親のテキストに移動します。

In [67]: myxml="""<data>
    ...:       <entry>
    ...:            <word>ABC</word> (this)
    ...:       </entry>
    ...:       <entry>
    ...:            <word>ABC</word> [not this]
    ...:       </entry>
    ...: </data>"""

In [68]: import StringIO, re, lxml.etree as ET

In [69]: f=StringIO.StringIO(myxml)

In [70]: data=ET.parse(f)

In [71]: print ET.tostring(data)
<data>
      <entry>
           <word>ABC</word> (this)
      </entry>
      <entry>
           <word>ABC</word> [not this]
      </entry>
</data>

In [72]: for elem in data.findall("/entry/"):
    ...:     if re.match(".*\(.*\).*",elem.tail):
    ...:         elem.getparent().text=elem.tail
    ...:         elem.tail=None
    ...:         

In [73]: print ET.tostring(data)
<data>
      <entry> (this)
      <word>ABC</word></entry>
      <entry>
           <word>ABC</word> [not this]
      </entry>
</data>
于 2013-02-03T06:35:15.733 に答える
0

ここにはいくつかの問題があります。

まず、xpathを使用して正規表現のマッチングを行おうとしていますが、=を使用しています。正規表現も不適切にフォーマットされています。xpathで実際に正規表現のマッチングを行うには、次のようなことを行う必要があります。

import lxml.etree as ET
data = ET.parse('sample.xml')
regexpNS = "http://exslt.org/regular-expressions"
for entry in data.iter('entry'):
    A = entry.xpath('.//*[re:test(text(), ".*\(.*\).*")]',
                    namespaces={'re':regexpNS})

残念ながら、これは実際には機能しません。これは、に含まれていないテキストをテールに含める必要があるためですtext()。lxmlのドキュメントでは、これをに含める必要があるように見えますがstring()、試してみましたが、どちらも機能しません。xpathとlxmlを使用してこれを行う方法が見つかりません。

したがって、Pythonを増やしてxpathを減らしてそれを行う方法は次のとおりです。

 import re
 import lxml.etree as ET
 rx = re.compile('.*\(.*\).*')
 data = ET.parse('sample.xml')
 for entry in data.iter('entry'):
    for child in entry.xpath('.//*'):
        if rx.match(child.text + child.tail):
            # Your manipulations go here
            print child

どちらの場合でも、幸せな副作用は、この正規表現が雪の中で完全に揺れる楽しい時間を過ごしていることです.*\(.*\).*

于 2013-02-03T06:38:59.923 に答える