92178


xmlでdocumentに対して、テキストの数値がarticle-
id_pmidであったらpassageの中のparagraphにfirstが含まれていたら抽出するというプログラムを作成しています。

paragraph抽出は、containsを用いたのですがテキストの数値がarticle-
id_pmidであるかという箇所が分からなかったので教えて頂きたいです.(xpathを用いてpmidを抽出して、テキストの数値と一致させるとかですかね?)  
article-id_pmidとparagraphが違うpassageの中にあるので難しいのかなとも少し思いました

**take.py**

[code]

    from bs4 import BeautifulSoup
    import csv
    
    #xmlファイル読み込み
    with open('1.xml','r',encoding='utf-8') as xml:      
        soup = BeautifulSoup(xml, 'xml')
    
    #passageの中のparagraphにfirstが含まれていたら抽出
    
    texts = soup.select('''
    passage >
       infon[key="type"]:-soup-contains("paragraph") ~ text:-soup-contains("first") 
    ''')
    text = [t.text for t in texts]
    xml.close()
    
    #実行結果を指定のファイルに保存
    with open ('take.txt','w')as txt:
      print(text,file=txt)
    txt.close
    
[/code]

**1.txt**

[code]

    1111
    2222
    
[/code]

**1.xml**

[code]

    <collection>
        <document>
        <id>32691</id>
            <passage>
                <infon key="article-id_pmid">1111</infon>
            </passage>
            <passage>
                <infon key="section_type">INTRO</infon>
                <infon key="type">paragraph</infon>
                <text>which was first diagnosed in Wuhan. </text>
            </passage>
        </document>
        <document>
            <id>31435</id>
            <passage>
            <infon key="article-id_pmid">2222</infon>
            </passage>
            <passage>
            <infon key="section_type">INTRO</infon>
            <infon key="type">paragraph</infon>
            <text>>Challenges for Vaccinologists in the first. </text>
            </passage>
        </document>
        <document>
            <id>35643</id>
            <passage>
            <infon key="article-id_pmid">3333</infon>
            </passage>
            <passage>
            <infon key="section_type">INTRO</infon>
            <infon key="type">paragraph</infon>
            <text>>decreased trade, high unemployment. </text>
            </passage>
        </document>
    </collection>
    
[/code]


CC BY-SA 4.0
2022-11-12T05:02:53.850
92177
2022-11-12T07:17:59.770
2022-11-12T07:17:59.770
3060
54656
question
python python3 xml
containsを用いた要素抽出についてです


> テキストの数値がarticle-id_pmidであったら

この「テキストの数値」というのは `1.txt` の中身だとして、CSS セレクタで選別してみます。

なお、`-soup-contains(...)` は引数を `OR` 条件で結合します。

[code]

    [XML element]:-soup-contains("1111", "2222")
    =>
    ("1111" in "XML element text") OR ("2222" in "XML element text")
    
[/code]

※ `-soup-contains()` はその名前の通りに `contain`(包含)であって exact match
ではないので、その点には注意が必要です

[code]

    from bs4 import BeautifulSoup
    
    #xmlファイル読み込み
    with open('1.xml', 'r', encoding='utf-8') as xml:
      soup = BeautifulSoup(xml, 'xml')
    
    #textファイル読み込み
    with open('1.txt') as f:
      nums = [n.strip() for n in f.readlines()]
    
    #passageの中のparagraphにfirstが含まれていたら抽出
    nums = ','.join(f'"{n}"' for n in nums)
    texts = soup.select(f'''
      document:has(> passage > infon[key="article-id_pmid"]:-soup-contains({nums})) >
        passage >
          infon[key="type"]:-soup-contains("paragraph") ~ text:-soup-contains("first")
    ''')
    text = [t.text for t in texts]
    
    #実行結果を指定のファイルに保存
    with open('take.txt', 'w') as txt:
      print('\n'.join(text), file=txt)
    
[/code]


CC BY-SA 4.0
2022-11-12T06:03:58.073
92178
2022-11-12T06:03:58.073
47127
92177
answer