【问题标题】:Parsing XML with Python用 Python 解析 XML
【发布时间】:2012-02-28 18:45:35
【问题描述】:

我有几个大的 .xml 文件。我想解析文件来做几件事。

我只想拔出:

  • XML-/title1 并将其保存到列表 A(例如)
  • XML-/title2 并将其保存到列表 B
  • XML-/title3 并将其保存到列表 C
  • 等等等等

使用 Python 2.x 最适合导入/使用的库。我该如何设置? 有什么建议吗?

例如:

 <PubmedArticle>
    <MedlineCitation Owner="NLM" Status="MEDLINE">
        <PMID Version="1">8981971</PMID>
        <Article PubModel="Print">
            <Journal>
                <ISSN IssnType="Print">0002-9297</ISSN>
                <JournalIssue CitedMedium="Print">
                    <Volume>60</Volume>
                    <Issue>1</Issue>
                    <PubDate>
                        <Year>1997</Year>
                        <Month>Jan</Month>
                    </PubDate>
                </JournalIssue>
                <Title>American journal of human genetics</Title>
                <ISOAbbreviation>Am. J. Hum. Genet.</ISOAbbreviation>
            </Journal>
            <ArticleTitle>mtDNA and Y chromosome-specific polymorphisms in modern Ojibwa: implications about the origin of their gene pool.</ArticleTitle>
            <Pagination>
                <MedlinePgn>241-4</MedlinePgn>
            </Pagination>
            <AuthorList CompleteYN="Y">
                <Author ValidYN="Y">
                    <LastName>Scozzari</LastName>
                    <ForeName>R</ForeName>
                    <Initials>R</Initials>
                </Author>
            </AuthorList>
        <MeshHeadingList>
            <MeshHeading>
                <DescriptorName MajorTopicYN="N">Alleles</DescriptorName>
            </MeshHeading>
            <MeshHeading>
                <DescriptorName MajorTopicYN="Y">Y Chromosome</DescriptorName>
            </MeshHeading>
        </MeshHeadingList>
        <OtherID Source="NLM">PMC1712541</OtherID>
    </MedlineCitation>
</PubmedArticle>

【问题讨论】:

  • 我会使用xml.dom.minidom,它带有 Python 并且工作正常。 lxml 是另一个不错的库,但您必须安装它。

标签: python xml


【解决方案1】:

尝试查看lxml 模块。

要定位标题,您可以将Xpath 与 lxml 一起使用,或者您可以使用 lxml 中的 xml 对象结构来“索引”您到标题元素。

【讨论】:

    【解决方案2】:

    尝试使用Beautiful soup。我发现这个库非常方便。正如刚才所指出的,BeautifulStoneSoup 专门用于解析 XML。

    【讨论】:

    • 具体来说,BeautifulStoneSoup
    • 谢谢大家,我选择 BeautifulSoup 作为我的路线。我发现 B.S.文档比 lxml 更清晰。
    • 在新版本的文档中:不再有BeautifulStoneSoup 类用于解析XML。要解析 XML,您将“xml”作为第二个参数传递给 BeautifulSoup 构造函数。
    • 我还没有阅读新文档。随意编辑我的答案。谢谢
    【解决方案3】:

    我不确定您为什么希望每个标题都在自己的列表中,您的问题让我相信。

    一个列表中的所有标题怎么样?以下示例使用您的示例 XML 的修剪版本,另外我复制了一个 &lt;Article/&gt; 以显示使用 lxml.etree.xpath 为您创建了 &lt;Title/&gt;'s 列表:

    >>> import lxml.etree
    
    >>> xml_text = """<PubmedArticle>
      <MedlineCitation Owner="NLM" Status="MEDLINE">
        <PMID Version="1">8981971</PMID>
        <Article PubModel="Print">
          <Journal>
            <ISSN IssnType="Print">0002-9297</ISSN>
            <!-- <JournalIssue ... /> -->
            <Title>American journal of human genetics</Title>
            <ISOAbbreviation>Am. J. Hum. Genet.</ISOAbbreviation>
          </Journal>
          <ArticleTitle>mtDNA and Y chromosome-specific polymorphisms in modern Ojibwa: implications about the origin of their gene pool.</ArticleTitle>
          <!--<Pagination>
              ...
              </MeshHeadingList>-->
          <OtherID Source="NLM">PMC1712541</OtherID>
        </Article>
        <Article PubModel="Print">
          <Journal>
            <ISSN IssnType="Print">9297-0002</ISSN>
            <!-- <JournalIssue ... /> -->
            <Title>American Journal of Pediatrics</Title>
            <ISOAbbreviation>Am. J. Ped.</ISOAbbreviation>
          </Journal>
          <ArticleTitle>Healthy Foo, Healthy Bar</ArticleTitle>
          <!--<Pagination>
              ...
              </MeshHeadingList>-->
          <OtherID Source="NLM">PMC1712541</OtherID>
        </Article>
      </MedlineCitation>
    </PubmedArticle>"""
    

    XPath 用于返回 lxml.etree.xpath 转换为 Python 节点对象列表的节点:

    >>> xml_obj = lxml.etree.fromstring(xml_text)
    >>> for title_obj in xml_obj.xpath('//Article/Journal/Title'):
            print title_obj.text 
    
    American journal of human genetics
    American Journal of Pediatrics
    

    编辑 1:现在使用 Python 的 xml.etree.ElementTree

    我想用包含的模块展示这个解决方案,以防安装第三方模块是不可能或没有吸引力的。

    >>> import xml.etree.ElementTree as ETree
    >>> element = ETree.fromstring(xml_text)
    >>> xml_obj = ETree.ElementTree(element)
    >>> for title_obj in xml_obj.findall('.//Article/Journal/Title'):
        print title_obj.text
    
    
    American journal of human genetics
    American Journal of Pediatrics
    

    它很小,但这个 XPathlxml 示例中的 XPath 相同:开头有一个句点 ('.')。没有句号,我收到了这个警告(使用 Python 2.7.2):

    >>> xml_obj.findall('//Article/Journal/Title')
    
    Warning (from warnings module):
      File "__main__", line 1
    FutureWarning: This search is broken in 1.3 and earlier, and will be fixed in a future version.  If you rely on the current behaviour, change it to './/Article/Journal/Title'
    

    【讨论】:

    • 我终于有时间查看所有发布的答案。感谢您的努力!我能够安装 lxml 库没问题,但是我在阅读文档时花了很多时间。当时,我只是无法转过头来。我发现 BeautifulSoup 的文档更容易处理。
    【解决方案4】:

    试试lxmlxpath expressions

    一个简短的sn-p

    >>> from lxml import etree
    >>> xml = """<foo><bar/>baz!</foo>"""
    >>> doc = etree.fromstring(xml)
    >>> doc.xpath('//foo/text()') #xpath expr
    ['baz!']
    >>>
    

    如果你有一个xml file

    s = StringIO(xml)
    doc = etree.parse(s)
    

    您可以使用Firebug addon 获取xpath expr

    【讨论】:

      【解决方案5】:

      ElementTree 非常棒,并且带有 Python。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-06
        • 2015-05-31
        • 2022-01-24
        相关资源
        最近更新 更多