2017-04-24 12 views
1

Python ElementTree/lxml(pydev)を使用してxmlファイルを解析しています。キーワード検索に基づいてPythonを使用してxmlファイルから値を抽出する

EDIT:完全なXMLファイル:

[https://pastebin.com/embed_js/Gbrv9wgG]

私は、コメント内のキーワードとして 'ROTARY' を含むすべてのsignalnamesを抽出しようとしています。 XMLファイルには、 'CHANNEL'という子を持つものと持たないものがあります。

現在、私はSignalnames対応するすべてのコメントと印刷にのみキーワード「ROTARY」を検索するlxmlのかElementTreeのを使用することができません

import xml.etree.ElementTree as ET 
tree=ET.parse('Project.xml') 
root=tree.getroot() 
for comments in root.iter('COMMENT') 
    print(comments.text) 

をプリントアウトし、すべてのコメントがあります。

...

for word in root.xpath('.//CHANNEL[COMMENT[contains(text(),"ROTARY")]]"/COMMENT/text()'): 
print (word) 

任意の出力を取得できませんでした私はPythonとXMLに新しいですので、任意のヘルプは高く評価されます: 私は、次のコードを使用していました。

答えて

0

xml.etree.ElementTreeの代わりに、BeautifulSoupを使用してXMLの内容を解析することができます。

このコードはします:

  1. <CHANNEL>が出現するたびに<CHANNEL></CHANNEL>タグ
  2. のすべての出現のためのsoup XMLコンテンツを使用して
  3. 検索を作成、それは内部の単語'ROTARY'を探します<COMMENT>タグ。
  4. 'ROTARY'という単語が見つかった場合は、<SIGNALNAME>タグの値が印刷されます。

例コード:

s = '''<PROJECT> 
      <HARDWARE CONFIGURATION> 
      <PNIODEVICE> 
       <PNIOSLOT>    
      <CHANNEL> 
      <INDEX>2</INDEX> 
      <SUBADR>0</SUBADR> 
      <CHTYPE>E</CHTYPE> 
      <MASK>4</MASK> 
      <SIGNALNAME>ELE+S1-BGI51.2</SIGNALNAME> 
      <COMMENT>ROTARY TRANSFER RADIAL ALIGNMENT 00SWIV</COMMENT> 
      </CHANNEL> 
      <CHANNEL> 
      <INDEX>3</INDEX> 
      <SUBADR>0</SUBADR> 
      <CHTYPE>E</CHTYPE> 
      <MASK>8</MASK> 
      <SIGNALNAME>ELE+S1-BGI51.3</SIGNALNAME> 
      <COMMENT>ROTARY TRANSFER RADIAL ALIGNMENT 1800SW</COMMENT> 
      </CHANNEL> 
      <CHANNEL> 
      <INDEX>4</INDEX> 
      <SUBADR>0</SUBADR> 
      <CHTYPE>E</CHTYPE> 
      <MASK>10</MASK> 
      <SIGNALNAME>ELE+S1-BGI51.4_4C</SIGNALNAME> 
      <COMMENT>ROTARY TRANSFER TRANSPORT ARM RIGHT 00R</COMMENT> 
      </CHANNEL> 
     </PNIOSLOT> 
     </PNIODEV> 
     </HARDWARE> 
</PROJECT>''' 

from bs4 import BeautifulSoup 

soup = BeautifulSoup(s, 'lxml') 

channel_tags = soup.find_all('channel') 

for channel in channel_tags: 
    if 'ROTARY' in channel.comment.text: 
     print(channel.signalname) 

出力:

<signalname>ELE+S1-BGI51.2</signalname> 
<signalname>ELE+S1-BGI51.3</signalname> 
<signalname>ELE+S1-BGI51.4_4C</signalname> 

EDIT:

AttributeErrorは、try/exceptステートメントを使用してバイパスできます。

for channel in channel_tags: 
    try: 
     if 'ROTARY' in channel.comment.text: 
      print(channel.signalname) 
    except: 
     continue 
+0

ありがとうございます。私はBeautifulSoupで試してみます。 – vrindakm

+0

あなたの 'xml.etree'バグを手伝ってくれて申し訳ありません。私はこのライブラリでうまくいきません。少なくとも私のコードはあなたの望む出力を生成します。 :P –

+0

find_all( 'CHANNEL')自体のための空の配列を得る – vrindakm

0

あなただけEtreeを使用して出力を得ることができます: ここに述べた(と私は、この文書を通過することができアドバイスでしょう)として - https://docs.python.org/2/library/xml.etree.elementtree.html子供が入れ子になっている、と私たちは、インデックスによって特定の子ノードにアクセスすることができます

だから、あなたはこのような何かを行うことができます。

xmlに無効な文字が含まれています &あなた
for i in root[0][0][0]: # looping over CHANNELS 
    if 'ROTARY' in i[5].text: # if 'ROTARY' is in COMMENT 
     print i[4].text # print corresponding SIGNALNAME 
0

、それらを&amp;に置き換えることができます。
XMLを固定した後、あなたが使用することができます。

import xml.etree.ElementTree as ET 
tree=ET.parse('xml_test.xml') 
for channel in tree.findall('.//CHANNEL'): 
    if channel.find('COMMENT') is not None: 
     comment = channel.find('COMMENT') 
     if comment.text is not None: 
      if "ROTARY" in comment.text: 
       print channel.find('SIGNALNAME').text 

出力:

ELE+S1-BGI51.0_6C 
ELE+S1-BGI51.1_6C 
ELE+S1-BGI51.2 
ELE+S1-BGI51.3 
ELE+S1-BGI51.4_4C 
ELE+S1-BGI51.5_4C 
ELE+S1-BGI51.6 
ELE+S1-BGI51.7 
ELE+S1-BGI52.0 
... 
+0

私はこれを試しました...このエラーがあります: 'トレースバック(最新の最後の呼び出し): ファイル" C:\ Users \\ Pkg1 \ Py1.py "、行33、 ノードに" ROTARY " find( ".// COMMENT")。テキスト: AttributeError: 'NoneType'オブジェクトに 'text'属性がありません。 – vrindakm

+0

適切なヘルプを得るには、有効なxmlを投稿してください。 –

+0

私のXMLファイルはかなり巨大なので、私はすべての内容を追加することはできませんでした – vrindakm

0

使用XPATH

import xml.etree.ElementTree as ET 
tree =ET.parse('Project.xml').getroot() 
all_items = root.findall("HARDWARE/PNIODEVICE/PNIOSLOT/CHANNEL") 
lines = [item.find('SIGNALNAME').text for item in all_items if 'ROTARY' in item.find('COMMENT').text] 
print lines 

EDITED:あなたが持っていないことがあり、そのチャンネルを指定する必要がありますコメントタグ!

import xml.etree.ElementTree as ET 
root =ET.parse('project.xml').getroot() 
all_items = root.findall("HARDWARE/PNIODEVICE/PNIOSLOT/CHANNEL") 
lines = [item.find('SIGNALNAME').text for item in all_items if item.find('COMMENT') is not None and 'ROTARY' in item.find('COMMENT').text] 
print lines 
+0

こんにちは..ここでも同じエラーが出ます。 'lines = [item.find( 'SIGNALNAME')item.find( 'COMMENT')の 'ROTARY'の場合、all_itemsの項目のテキスト。 AttributeError: 'NoneType'オブジェクトに 'text'属性がありません – vrindakm

関連する問題