【问题标题】:Convert XML file to a list of lists in Python将 XML 文件转换为 Python 中的列表列表
【发布时间】:2020-12-14 06:58:09
【问题描述】:

我有一个来自HMDB 的数据集Saliva Metabolites 数据。

此数据是一个 XML 文件。我想要做的是将此 XML 文件转换为 Python 中的列表列表(嵌套列表),但是,我不希望列表中的所有节点。

已编辑:这是一种代谢物的部分数据示例

<?xml version="1.0" encoding="UTF-8"?>
<hmdb xmlns="http://www.hmdb.ca">
<metabolite>
  <version>4.0</version>
  <creation_date>2005-11-16 15:48:42 UTC</creation_date>
  <update_date>2019-01-11 19:13:56 UTC</update_date>
  <accession>HMDB0000001</accession>
  <status>quantified</status>
  <secondary_accessions>
    <accession>HMDB00001</accession>
    <accession>HMDB0004935</accession>
    <accession>HMDB0006703</accession>
    <accession>HMDB0006704</accession>
    <accession>HMDB04935</accession>
    <accession>HMDB06703</accession>
    <accession>HMDB06704</accession>
  </secondary_accessions>
  <name>1-Methylhistidine</name>
  <cs_description>1-Methylhistidine, also known as 1-mhis, belongs to the class of organic compounds known as histidine and derivatives. Histidine and derivatives are compounds containing cysteine or a derivative thereof resulting from reaction of cysteine at the amino group or the carboxy group, or from the replacement of any hydrogen of glycine by a heteroatom. 1-Methylhistidine has been found in human muscle and skeletal muscle tissues, and has also been detected in most biofluids, including cerebrospinal fluid, saliva, blood, and feces. Within the cell, 1-methylhistidine is primarily located in the cytoplasm. 1-Methylhistidine participates in a number of enzymatic reactions. In particular, 1-Methylhistidine and Beta-alanine can be converted into anserine; which is catalyzed by the enzyme carnosine synthase 1. In addition, Beta-Alanine and 1-methylhistidine can be biosynthesized from anserine; which is mediated by the enzyme cytosolic non-specific dipeptidase. In humans, 1-methylhistidine is involved in the histidine metabolism pathway. 1-Methylhistidine is also involved in the metabolic disorder called the histidinemia pathway.</cs_description>
  <description>One-methylhistidine (1-MHis) is derived mainly from the anserine of dietary flesh sources, especially poultry. The enzyme, carnosinase, splits anserine into b-alanine and 1-MHis. High levels of 1-MHis tend to inhibit the enzyme carnosinase and increase anserine levels. Conversely, genetic variants with deficient carnosinase activity in plasma show increased 1-MHis excretions when they consume a high meat diet. Reduced serum carnosinase activity is also found in patients with Parkinson's disease and multiple sclerosis and patients following a cerebrovascular accident. Vitamin E deficiency can lead to 1-methylhistidinuria from increased oxidative effects in skeletal muscle. 1-Methylhistidine is a biomarker for the consumption of meat, especially red meat.</description>
  <synonyms>
    <synonym>(2S)-2-amino-3-(1-Methyl-1H-imidazol-4-yl)propanoic acid</synonym>
    <synonym>1-Methylhistidine</synonym>
    <synonym>Pi-methylhistidine</synonym>
    <synonym>(2S)-2-amino-3-(1-Methyl-1H-imidazol-4-yl)propanoate</synonym>
    <synonym>1 Methylhistidine</synonym>
    <synonym>1-Methyl histidine</synonym>
  </synonyms>
  <chemical_formula>C7H11N3O2</chemical_formula>
  <smiles>CN1C=NC(C[C@H](N)C(O)=O)=C1</smiles>
  <inchikey>BRMWTNUJHUMWMS-LURJTMIESA-N</inchikey>
<diseases>
    <disease>
      <name>Kidney disease</name>
      <omim_id/>
      <references>
        <reference>
          <reference_text>McGregor DO, Dellow WJ, Lever M, George PM, Robson RA, Chambers ST: Dimethylglycine accumulates in uremia and predicts elevated plasma homocysteine concentrations. Kidney Int. 2001 Jun;59(6):2267-72.</reference_text>
          <pubmed_id>11380830</pubmed_id>
        </reference>
        <reference>
          <reference_text>Ehrenpreis ED, Salvino M, Craig RM: Improving the serum D-xylose test for the identification of patients with small intestinal malabsorption. J Clin Gastroenterol. 2001 Jul;33(1):36-40.</reference_text>
          <pubmed_id>11418788</pubmed_id>
        </reference>
        <reference>
         </reference>
      </references>
    </disease>
    <disease> 

导入文件:

import xml.etree.ElementTree as et

data1 = et.parse('D:/path/to/Tal/my/HMDB/DataSets/saliva_metabolites/saliva_metabolites.xml')
root = data1.getroot()

现在,不确定如何选择特定节点。意思是,我的目标是创建一个代谢物列表,列表中的每个代谢物都将包含一个节点列表(例如,&lt;accession&gt;&lt;name&gt;&lt;synonyms&gt;&lt;diseases_name&gt;

反过来,这些元素将包含另一个列表(例如,在&lt;synonyms&gt; 内部将有一个值名称列表,或者在&lt;diseases_name&gt; 内部将是疾病名称列表,每个疾病将包含一个pub_id 列表值)。

# To access the 4'th node of the first metabolit

>>  root[0][3].text
'HMDB0000001'

其中root[0][3] 代表&lt;accession&gt; 节点。

尝试使用 print 运行循环,所以我会理解循环的输出,但收到了 None 的列表

for node in root:
    print(node.find('accession'))
None
None
None
None
None
.
.
.

也试过了

>> root.findall('./metabolite/accession')
[]

但是收到了空括号

我尝试的第一个代谢物的同义词列表:

>> root[0][9].text
'\n    '

# This gave the first value of synonyms
root[0][9][0].text
'\n    '

我用这些问题找到了答案:

  1. How do I parse XML in Python?
  2. how to create a list of elements from an XML file in python
  3. Python: XML file to pandas dataframe
  4. Convert XML into Lists of Tags and Values with Python
  5. Generating nested lists from XML doc

任何提示、想法都会有所帮助,感谢您的宝贵时间

【问题讨论】:

    标签: python xml list elementtree


    【解决方案1】:

    您忽略了 XML 中的命名空间。

    <hmdb xmlns="http://www.hmdb.ca">
    

    表示没有&lt;hmdb&gt; 元素。 &lt;hmdb&gt; http://www.hmdb.ca 命名空间中。因为它是这个元素的默认命名空间,所以所有后代元素都在同一个命名空间中,除非它们覆盖它。

    所以这个

    root.findall('./metabolite/accession')
    

    不会返回任何内容,因为您在错误的命名空间中搜索。

    为方便起见,让我们在 http://www.hmdb.ca 命名空间中搜索,并为其提供句柄 h

    ns = {
        "h": "http://www.hmdb.ca"
    }
    
    accession = root.findall('./h:metabolite/h:accession', ns)
    print(accession)
    

    这会找到一个元素(查看它在打印时如何明确表示命名空间):

    [<Element '{http://www.hmdb.ca}accession' at 0x03E6E7B0>]
    

    您可以在 ElementTree 中使用相同的显式语法,但它很快就会变得笨拙:

    t.findall('./{http://www.hmdb.ca}metabolite/{http://www.hmdb.ca}accession')
    

    prefix: 的较短(和标准)语法更易于使用。

    【讨论】:

    • 或者使用通配符作为命名空间(Python 3.8):stackoverflow.com/a/62117710/407651
    • ...这是处理它的肮脏方式。我宁愿不马虎。
    • @Tomalak!感谢您的时间!当` print(accession)` 我没有看到加入的value 但它的位置 - [&lt;Element '{http://www.hmdb.ca}accession' at 0x03E6E7B0&gt;] 怎么来的?如果可以,还有另一个问题,我如何才能继续创建列表列表(嵌套列表)?再次感谢
    • @TaL .findall() 为您提供元素列表(在本例中长度为 1)。每个元素都有几个属性,它所包含的text 只是其中之一,因此您必须再采取一步来提取它。我想你会找到你自己的嵌套循环方式,这样你就会得到你想要的嵌套列表,你不需要我为你拼出来。
    猜你喜欢
    • 2022-01-11
    • 2019-02-23
    • 2016-07-11
    • 2016-01-15
    • 2013-08-13
    • 2012-08-13
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多