【问题标题】:Unable to read sibling and child of the sibling from XML file无法从 XML 文件中读取兄弟姐妹和兄弟姐妹的孩子
【发布时间】:2019-08-21 13:46:49
【问题描述】:

我想从 xml 文件中读取 PMID 和作者名字,示例文件如下所示

我得到了 PMID 和名字,但循环是 PMID 的次数,我想要 1 个 PMID 和相应的名字

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE PubmedArticleSet SYSTEM "http://dtd.nlm.nih.gov/ncbi/pubmed/out/pubmed_190101.dtd">
<PubmedArticleSet>
<PubmedArticle>
    <MedlineCitation Status="MEDLINE" Owner="NLM">
        <PMID Version="1">2844048</PMID>
        <AuthorList CompleteYN="Y">
            <Author ValidYN="Y">
                <LastName>Guarner</LastName>
                <ForeName>J</ForeName>
                <Initials>J</Initials>
            </Author>
            <Author ValidYN="Y">
                <LastName>Cohen</LastName>
                <ForeName>C</ForeName>
                <Initials>C</Initials>
            </Author>
            <Author ValidYN="Y">
                <LastName>Mushi</LastName>
                <ForeName>E</ForeName>
                <Initials>F</Initials>
            </Author>
        </AuthorList>
    </MedlineCitation>
</PubmedArticle>
<PubmedArticle>
    <MedlineCitation Status="MEDLINE" Owner="NLM">
        <PMID Version="1">123456</PMID>
        <AuthorList CompleteYN="Y">
            <Author ValidYN="Y">
                <LastName>Smith</LastName>
                <ForeName>C</ForeName>
                <Initials>C</Initials>
            </Author>
            <Author ValidYN="Y">
                <LastName>Jones</LastName>
                <ForeName>E</ForeName>
                <Initials>F</Initials>
            </Author>
        </AuthorList>
    </MedlineCitation>
</PubmedArticle>
</PubmedArticleSet>

代码,我试过了

FN=[]
for pmid in root.iter('PMID'):
    print(pmid.text)
    for id in root.findall("./PubmedArticle/MedlineCitation/Article/AuthorList"):
        for f in id.findall("./Author/ForeName"):
            fn=f.text

            x= '{},{}'.format(i, fn)
            #print(x)
            FN.append(x)

预期输出

PMID               AUTHORS
2844048            'Guarner J J', 'Cohen C C'

【问题讨论】:

    标签: python xml python-3.x python-2.7 xml-parsing


    【解决方案1】:

    我不知道您是否希望输出为特定格式。但是,您可以尝试以下代码。输出是一个字典,其中键是 PMID,值是作者列表。

    import xml.etree.ElementTree as ET
    import pandas as pd
    tree = ET.parse('E:\Python\DataFiles\PMID.xml') # change according to your location
    authors_pmid = []
    all_authors_pmid = []
    root = tree.getroot()
    for amedlinecitation in root.iter('MedlineCitation'): #PMID and Author are childs of MedlineCitation
        pmid = amedlinecitation.find('PMID').text
        for anauthor in amedlinecitation.iter('Author'): # for each amedlinecitation, find all its Authors
            author_name = anauthor.find('LastName').text # for each Author, find the LastName tag and extract its value
            authors_pmid = [pmid,author_name]
            all_authors_pmid.append(authors_pmid)
    df = pd.DataFrame(all_authors_pmid,columns=['PMID','Author'])
    print(df)
    

    输出:

    {'2844048': ['Guarner', 'Cohen', 'Mushi'], '123456': ['Smith', 'Jones']}
    

    以下代码将使用 Python Dataframe 以表格形式提供输出。

    import xml.etree.ElementTree as ET
    import pandas as pd
    tree = ET.parse('E:\Python\DataFiles\PMID.xml') # change according to your location
    authors_pmid = []
    all_authors_pmid = []
    root = tree.getroot()
    for amedlinecitation in root.iter('MedlineCitation'): #PMID and Author are childs of MedlineCitation
        pmid = amedlinecitation.find('PMID').text
        for anauthor in amedlinecitation.iter('Author'): # for each amedlinecitation, find all its Authors
            author_name = anauthor.find('LastName').text # for each Author, find the LastName tag and extract its value
            authors_pmid = [pmid,author_name]
            all_authors_pmid.append(authors_pmid)
    df = pd.DataFrame(all_authors_pmid,columns=['PMID','Author'])
    print(df)
    

    输出:

          PMID   Author
    0  2844048  Guarner
    1  2844048    Cohen
    2  2844048    Mushi
    3   123456    Smith
    4   123456    Jones
    

    上面的代码和第一个代码有什么不同:

    1. 对于每对 PMID 和作者姓名,它将创建一个列表。此列表名为 authors_pmid。例如,['2844048', 'Guarner'], ['2844048', 'Cohen'], ['2844048', 'Mushi'], ['123456', 'Smith'], ['123456', 'Jones '] 将是内部 for 循环每次迭代期间列表变量 authors_pmid 中的值。
    2. 然后上述每个列表都将附加到由 all_authors_pmid 定义的最终列表中
    3. 这个最终列表将是调用 Dataframe 构造函数的数据输入,以创建列名称为:PMID 和 Author 的 Dataframe

    【讨论】:

    • 非常感谢,{'2844048': ['Guarner', 'Cohen', 'Mushi'], 我能得到像 2844048' Guarner' '2844048':Cohen 2844048:Mushi 这样的输入吗?
    • 在整个文件上运行代码时,出现错误,AttributeError: 'NoneType' object has no attribute 'text', getting author_name = anauthor.find('ForeName').text跨度>
    • 你想要像 {2844048:'Guarner', 2844048:'Cohen', 2844048:'Mushi'} 这样的字典形式的输出吗?这是不可能的,因为 Dictionary 具有唯一的键。因此,键 2844048 在字典中只能出现一次,并且将具有最后输入的值。之前写入的任何值都将被新值覆盖。如果您希望多个值属于一个键,则制作这些值的列表并将其分配给该键。这就是我上面的代码所做的。
    • 关于错误,“AttributeError: 'NoneType' object has no attribute 'text', getting author_name = anauthor.find('ForeName').text”,我很难评论知道你正在运行什么代码。
    • 我解决了属性错误,不,我想在数据框中输入像第一行 2844048'Guarner',第二行 2844048:'Mushi.有可能吗?
    猜你喜欢
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多