53392


科研費のデータベース（XML形式）から、必要な要素だけを抽出して一覧表を作ることを考えています。  
<https://kaken.nii.ac.jp/ja/>

lxmlパッケージのetreeを利用し、

[code]

    tree = etree.parse('ファイル名')
    root = tree.getroot()
    
    grantAwardsGakubu = tree.xpath('/grantAwards/grantAward/summary[@xml:lang="ja"]/member[@sequence="1"]/department')  # 1stの所属学部
    grantAwards = tree.xpath('/grantAwards/grantAward/summary[@xml:lang="ja"]/member[@sequence="1"]/personalName[@sequence="1"]/fullName')  # 1st（和文）の名前
    
[/code]

として要素の抽出を行ったのですが、所属学部が未定義になっているデータが１件あるようで、名前と並びがズレてしまいます。所属学部が未定義になっているものはnullを入れるなりして、空行にしたいのですが、何か良い手はないものでしょうか。

データは、例えば下記のリンクを開いて、  
[https://kaken.nii.ac.jp/ja/search/?kw=%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6&o1=1&s1=2018&s2=2018&fc=ca%3A%E5%9F%BA%E7%9B%A4%E7%A0%94%E7%A9%B6(S)%2F000060](https://kaken.nii.ac.jp/ja/search/?kw=%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6&o1=1&s1=2018&s2=2018&fc=ca%3A%E5%9F%BA%E7%9B%A4%E7%A0%94%E7%A9%B6\(S\)%2F000060)  
画面上の方にある[XMLで出力]の隣の実行ボタンを押すとダウンロードできます。

よろしくお願いいたします。


CC BY-SA 4.0
2019-03-12T13:49:45.203
53390
2019-03-12T15:41:22.507
2019-03-12T15:22:58.383
12561
32510
question
python python3 xpath
xpathでデータが未定義の箇所がある場合、どのように例外処理をすれば良いか


一旦、基準となる要素(今回はmemberタグ)のリスト取得した後、各要素の子要素をループで取得し、処理すればよいのではないでしょうか。

コードにすると以下のような感じです。

[code]

    from lxml import etree
    
    tree = etree.parse('ファイル名')
    root = tree.getroot()
    
    # 1stの取得
    members = tree.xpath('/grantAwards/grantAward/summary[@xml:lang="ja"]/member[@sequence="1"]')
    
    grantAwardsGakubu = list()
    grantAwards = list()
    
    if len(members):
        for m in members:
    
            # 1stの詳細な情報を取得
            department = m.xpath('department')
            full_name   = m.xpath('personalName[@sequence="1"]/fullName')
    
            # -- 以降適当な処理を実施する --
            # 以下は例として文字列のリストを作っている
    
            if len(department) :
              grantAwardsGakubu.append(department[0].text)
            else:
              grantAwardsGakubu.append("")
    
    
            if len(full_name) :
              grantAwards.append(full_name[0].text)
            else:
              grantAwards.append("")
    
    
[/code]

※データを拝見したところ、memberタグが各研究者の情報を示し、より詳細な情報(部署なり機関なり)が入れ子になった子要素の中に格納されているようです。  
このため基準となるのは`'/grantAwards/grantAward/summary[@xml:lang="ja"]/member[@sequence="1"]'`になります。  
(雑に例えるなら、memberタグが名札のようなものだと考えてください。名札の各欄(departmentなりfullNameなり)に入っている値を名札単位で値を読み取っている、とでも考えていただければよいかと)


CC BY-SA 4.0
2019-03-12T14:52:06.047
53392
2019-03-12T15:41:22.507
2019-03-12T15:41:22.507
12561
12561
53390
answer