使用 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 列表 中(稍后从您的脚本中获取属性过滤)。
如果需要,您可以进行更多过滤。
我有一个 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 列表 中(稍后从您的脚本中获取属性过滤)。
如果需要,您可以进行更多过滤。