如何在xml文件中找到具有正确日期类型代码的日期



我正在用python (3.7) Elementree解析xml文件,目的是更改其中的日期。但是,由于目前有三个日期,我需要在不修改其他日期的情况下找出正确的日期进行编辑。XML部分如下所示(如果格式关闭,请道歉):

<CI_Citation>
<date>
<CI_Date>
<date>
<gco:Date>2003-07-01</gco:Date>
</date>
<dateType>
<CI_DateTypeCode CodeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="ISOTC211/19115">creation</CI_DateTypeCode>
</dateType>
</CI_Date>
</date>
<date>
<CI_Date>
<date>
<gco:Date>2003-07-01</gco:Date>
</date>
<dateType>
<CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="publication" codeSpace="ISOTC211/19115">publication</CI_DateTypeCode>
</dateType>
</CI_Date>
</date>
<date>
<CI_Date>
<date>
<gco:Date>2022-12-02</gco:Date>
</date>
<dateType>
<CI_DateTypeCode CodeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="revision" codeSpace="ISOTC211/19115">revision</CI_DateTypeCode>
</dateType>
</CI_Date>
</date>
</CI_Citation>

根据名称空间,我可以毫不费力地找到三个日期,但是这三个日期如何获得修订类型代码?据我所知,日期节点的路径都是相同的,但是附带的DateType应该告诉我要编辑哪个,但是它们在同一级别上。

我用以下函数遍历XML文件:

def etree_iter_path(node, rpath, tag=None):
if tag == "*":
tag = None
if tag is None or node.tag == tag:
yield node, rpath
for child in node:
_child_path = '%s/%s' % (rpath, child.tag)
for subchild, subchild_path in etree_iter_path(child, tag=child.tag, rpath=_child_path):
yield subchild, subchild_path

使用ElementTree解析XML文件,然后使用getroot()并使用函数遍历所有节点,这样我将找到日期和日期类型作为单独的实体,这使得修改日期和日期类型成为不可能(至少我目前是这样认为的)。任何想法吗?

我希望找到日期和日期类型作为一对,而不是单独的实体,所以xml树中的完整路径将很容易找到。

我错过了XML根标记中的namespace!在此更正之后,我建议创建一个元组列表,例如(date, type),以更改日期。不清楚你想改变什么。编辑或格式化日期。

在这里你可以找到我的想法来解析你的xml在一个数据框架:

import pandas as pd
import xml.etree.ElementTree as ET
tree = ET.parse('dateRevision.xml')
root = tree.getroot()
ns = "{http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode}"
columns = ["Date", "CI_DateTypeCode_attribute", "CI_DateTypeCode_text" ]
gco_list = []
for elem in root.findall("./date/CI_Date"):
row = []
for gco_date in elem.iter():
if gco_date.tag == f"{ns}Date":  
gcodate = gco_date.text
if gco_date.tag == "CI_DateTypeCode":
type_attrib = gco_date.get('codeListValue')
type_text = gco_date.text
row = [gcodate, type_attrib, type_text]    
gco_list.append(row)
row = []

df = pd.DataFrame(gco_list, columns=columns)
print(df)

输出:

Date CI_DateTypeCode_attribute CI_DateTypeCode_text
0  2003-07-01                  creation             creation
1  2003-07-01               publication          publication
2  2022-12-02                  revision             revision