使用 python 从 xml 个子字段中提取数据

extract data from xml subfields using python

我有一个 xml 文件,我想从中提取数据。我尝试使用 python,但是当我尝试使用我在网上找到的示例脚本时,我无法提取我想要的数据。 我在以下位置找到了一个脚本:https://medium.com/analytics-vidhya/parsing-xml-files-in-python-d7c136bb9aa5 它能够从给定的示例中提取数据,但是当我尝试将它应用到我的 xml 时,我无法让它工作。这是我的 xml 文件:https://pastebin.com/Q4HTYacM(大约 200 行长,这就是我将其粘贴到 pastebin 的原因)

我感兴趣的数据可以在

<datafield  tag="100" ind1="1" ind2=" "> <!--VerfasserIn-->
   <subfield code="a">Ullenboom, Christian</subfield>
   <subfield code="e">VerfasserIn</subfield>
   <subfield code="0">(DE-588)123404738</subfield>
   <subfield code="0">(DE-627)502584122</subfield>
   <subfield code="0">(DE-576)184619254</subfield>
   <subfield code="4">aut</subfield>
</datafield>

场,以及其他一些。问题是,我对 <subfield code="a">Ullenboom, Christian</subfield> 感兴趣 但我无法提取它,因为 root=tree.getroot() 似乎只将第一行计为可搜索行,我还没有找到任何方法来搜索特定的数据字段。

感谢任何帮助。

编辑:我的脚本:

## source: https://medium.com/analytics-vidhya/parsing-xml-files-in-python-d7c136bb9aa5

# import libs
import pandas as pd
import numpy as np
import glob

import xml.etree.cElementTree as et


#parse the file
tree=et.parse(glob.glob('./**/*baselinexml.xml',recursive=True)[0])

root=root.getroot()
#create list for values
creator = []
titlebook = []
VerfasserIn = []

# Converting the data
for creator in root.iter('datafield tag="100" '):
    print(creator)
print("step1")
creator.append(VerfasserIn)
for titlebook in root.iter('datafield tag="245" ind1="1" ind2="0"'):
    print(titlebook.text)


# creating dataframe

Jobs_df = pd.DataFrame(
list(zip(creator, titlebook)),
columns=['creator','titlebook'])
#saving as .csv

Jobs_df.to_csv("sample-api1.csv")

我对这种编程还很陌生,所以我尝试修改示例中的代码

列表[Python.Docs]: xml.etree.ElementTree - The ElementTree XML API,您会在那里找到您需要知道的一切。

您在 PasteBin 上发布的 XML 不完整(因此无效)。最后少了</zs:recordData></zs:record></zs:records></zs:searchRetrieveResponse>

命名空间的存在使事情变得复杂,因为(真实的)节点标记不是文件中的文字字符串。你应该坚持命名空间,还有上面URL.

中的XPath

这是一个变体。

code00.py:

#!/usr/bin/env python

import sys
from xml.etree import ElementTree as ET


def main(*argv):
    doc = ET.parse("./blob.xml")  # Saved (and corrected) the file from PasteBin
    root = doc.getroot()
    namespaces = {  # Manually extracted from the XML file, but there could be code written to automatically do that.
        "zs": "http://www.loc.gov/zing/srw/",
        "": "http://www.loc.gov/MARC21/slim",
    }
    #print(root)
    datafield_nodes_path = "./zs:records/zs:record/zs:recordData/record/datafield"  # XPath
    datafield_attribute_filters = [
        {
            "tag": "100",
            "ind1": "1",
            "ind2": " ",
        },
        {
            "tag": "245",
            "ind1": "1",
            "ind2": "0",
        },
    ]
    #datafield_attribute_filters = []  # Decomment this line to clear filters (and process each datafield node)
    ret = []
    for datafield_node in root.iterfind(datafield_nodes_path, namespaces=namespaces):
        if datafield_attribute_filters:
            skip_node = True
            for attr_dict in datafield_attribute_filters:
                for k, v in attr_dict.items():
                    if datafield_node.get(k) != v:
                        break
                else:
                    skip_node = False
                    break
            if skip_node:
                continue
        for subfield_node in datafield_node.iterfind("./subfield[@code='a']", namespaces=namespaces):
            ret.append(subfield_node.text)
    print("Results:")
    for i, e in enumerate(ret, start=1):
        print("{:2d}: {:s}".format(i, e))


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

输出:

[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\q071724477]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" code00.py
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32

Results:
 1: Ullenboom, Christian
 2: Java ist auch eine Insel

Done.

在上面的示例中,我提取了每个 subfield 节点的文本(code 属性的值为 a) 是 datafield 节点 的子节点,其属性与条目之一匹配在 datafield_attribute_filters 列表 中(稍后从您的脚本中获取属性过滤)。
如果需要,您可以进行更多过滤。