如何获取XML标记内的所有文本

时间:2018-04-11 20:16:03

标签: python xml parsing

here

从上面.xml文件我正在提取文章ID,文章标题,摘要和关键字。对于单个标签内的正常文本获得正确的结果。但是带有多个标签的文本如:

  OrderedDict([(u'italic**', u'Rapidithrix thailandica'), ('#text', u'Acetylcholines terase-Inhibiting Activity of Pyrrole Derivatives from a Novel Marine Gliding Ba cterium,')])

我的输出为:

import xmltodict
import os
from os.path import basename
import re


with open('2630847.nxml') as fd:
    doc = xmltodict.parse(fd.read())
    pmc_id = doc['article']['front']['article-meta']['article-id'][1]['#text']

    article_title = doc['article']['front']['article-meta']['title-group']['article-title']

    y = doc['article']['front']['article-meta']['abstract']
    y = y.items()[0]
    article_abstract = [g.encode('ascii','ignore') for g in y][1]

    z = doc['article']['front']['article-meta']['kwd-group']['kwd']
    zz = [g.encode('ascii','ignore') for g in z]
    article_keywords = ",".join(zz).replace(","," ")


    fout = open(str(pmc_id)+".txt","w")
    fout.write(str(pmc_id)+"\n"+str(article_title)+". "+str(article_abstract)+". "+str(article_keywords))

代码将标记视为文本,生成的o / p也不在序列中。

如何简单地从这样的输入文档中提取文本 "来自新型海洋滑翔细菌,泰国的Rapidithrix的吡咯衍生物的乙酰胆碱酯酶抑制活性"

我使用下面的python代码来执行上述任务..

String dataStr = "[{\"DIMNAME\":\"d11\",\"DIMID\":\"11\"},{\"DIMNAME\":\"d12\",\"DIMID\":\"12\"}]";
try {
    JSONArray cadDims = new JSONArray(dataStr);
} catch (JSONException ex) {
    Logger.getLogger(EnCad.class.getName()).log(Level.SEVERE, null, ex);
}

有人可以建议更正..

1 个答案:

答案 0 :(得分:0)

xmltodict可能很难用于您的数据。 PMC期刊文章绝对不是不是作者可能想到的。将任何但最简单的XML放入xmltodict中的方法是将一个圆形的钉子敲入方孔 - 你可能会成功,但它不会很漂亮。我在下面的“tldr”....

下进一步解释

相反,我建议您使用其数据模型更适合您的数据的库,例如xml.dom,minidom或BeautifulSoup的最新版本。在许多这样的库中,您只需通过一次调用加载文档,然后调用一些函数(如innerText())来获取它的所有文本内容。您甚至可以将文档加载到浏览器中并调用Javascript innerText()函数来获取所需内容。如果您选择的工具不提供innertext(),则为:

def innertext(node):
    t = ""
    for curNode in node.childNodes:
        if (isinstance(curNode, Text)):
            t += curNode.nodeValue
        elif (isinstance(curNode, Element)):
            t += curNode.innerText
    return(t)

您可以调整它以在文本节点之间放置空格,具体取决于您的数据。

希望有所帮助。

== tldr ==

xmltodict做出令人钦佩的尝试,使XML“尽可能简单”;但恕我直言,它使它更简单错误。

xmltodict基本上是通过将每个元素转换为dict来实现的,其子元素作为dict项,由元素名称键入。但在许多情况下(例如你的),XML数据根本不是那样的。例如,一个元素可以有许多具有相同名称的子元素,但是dict不能。

因此xmltodict必须做一些特别的事情。它将相同元素类型的相邻实例转换为数组(没有元素类型)。以下是摘自https://github.com/martinblech/xmltodict)的示例:

<and>
  <many>elements</many>
  <many>more elements</many>
</and>

变为:

"and": {
    "many": [
        "elements", 
        "more elements"
    ]
}, 

首先,这意味着xmltodict总是会丢失有关子元素的排序信息,除非它们属于同一类型。因此,包含段落,列表,块引用等组合的部分将无法在xmltodict中加载,或者将每种子级的所有分散实例聚集在一起,完全失去其顺序。

xmltodict方法还引入了频繁的特殊情况 - 例如,您不仅可以获取所有子节点的列表,还可以使用len()来查找有多少子节点等等,因为在每一步都要检查你是否真的处于子元素或者列表中。

看看xmltodict自己的例子,你会发现它们主要是按元素名称向下走树,但是偶尔有一个整数下标 - 这就是需要这些数组的情况。但除非数据非常简单(你的数据不是这样),否则你不会知道它在哪里。例如,如果HTML文档中的一个DIV恰好只包含一个P,则访问P的代码需要的下标少于另一个恰好具有多个P的DIV。

在我看来,下标的数量是不可取的,取决于它有多少兄弟姐妹及其类型。

唉,结构还不够好。由于子元素可能有自己的子元素,因此仅仅使用额外数组中的字符串是不够的。有时它们必须再次成为dicts,其中一些项目可能依次是数组,其中一些项目可能是dicts,依此类推。编写正确的遍历算法来收集文本比上面显示的DOM要困难得多。

为了完全公平, 某些XML,其中顺序与逻辑无关 - 例如,您可以将SQL表导出到XML文件中,每个使用容器元素记录每个字段的子元素。字段的顺序不是信息,因此如果将此类XML加载到xmltodict中,则丢失顺序无关紧要。同样,如果您序列化已经只是一个字典的Python数据。但那些是非常专业的边缘情况。对于这样的案例来说,xmltodict可能是一个很好的选择 - 但是你所看到的文章距离它很远。