我有一个python脚本,它使用lxml来更改特定标记的值。我有以下xml
CALL SumCountAllDays( '2012-12-01',
'2012-12-31' );
对于每种不同的日期类型(出版,创建和修订),我想将日期更改为特定日期,但所有3的标签都相同 -
<gmd:CI_Citation> <gmd:date> <gmd:CI_Date> <gmd:date> <gco:Date>**1900-01-01**</gco:Date> </gmd:date> <gmd:dateType> <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="publication">Publication</gmd:CI_DateTypeCode> </gmd:dateType> </gmd:CI_Date> </gmd:date> <gmd:date> <gmd:CI_Date> <gmd:date> <gco:Date>**1900-01-01**</gco:Date> </gmd:date> <gmd:dateType> <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation">Creation</gmd:CI_DateTypeCode> </gmd:dateType> </gmd:CI_Date> </gmd:date> <gmd:date> <gmd:CI_Date> <gmd:date> <gco:Date>**1900-01-01**</gco:Date> </gmd:date> <gmd:dateType> <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="revision">Revision</gmd:CI_DateTypeCode> </gmd:dateType> </gmd:CI_Date> </gmd:date> </gmd:CI_Citation>
我正在使用以下函数来更改值
//:gmd_citation/:gmd_CI:Citation/:gmd_date/:gmd_CI_Date/:gmd_date/:gco_Date
使用xpath获取特定标记的最佳方法是什么,以便可以更改该值?
答案 0 :(得分:1)
这是我使用xpath获取特定元素并编辑它们的方法:
# Find the best implementation available on the platform
try:
from cStringIO import StringIO
except:
from StringIO import StringIO
from lxml import etree
# proper namespaces added to get valid xml
xmlstr = StringIO("""<gmd:CI_Citation xmlns:gmd="http://gmd.example.com" xmlns:gco="http://gco.example.com">
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:Date>1900-01-01</gco:Date>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="publication">Publication</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:Date>1900-01-01</gco:Date>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:Date>1900-01-01</gco:Date>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="revision">Revision</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
</gmd:CI_Citation>""")
tree = etree.parse(xmlstr)
这里我们使用xpath来获取所有(3)目标元素。
targets = tree.xpath('/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode', \
namespaces={'gmd': "http://gmd.example.com", 'gco': "http://gco.example.com"})
这三个元素由唯一属性值区分,
可以使用简单的函数hasattr
def hasattr(elem, att, val):
try:
return elem.attrib[att] == val
except:
return False
targets [0] codeListValue / text node:&#34; publication&#34; /&#34; Publication&#34;
目标[1] codeListValue / text节点:&#34;创建&#34; /&#34;创建&#34;
targets [2] codeListValue / text node:&#34; revision&#34; /&#34; revision&#34;
哪一个需要改变?
hasattr(targets[0], 'codeListValue', 'publication') # True
hasattr(targets[1], 'codeListValue', 'creation') # True
hasattr(targets[2], 'codeListValue', 'publication') # False
# Let's change one of them
t1 = targets[1]
t1.text = 'New Creation' # change text node
# and/or change attribute
t1.attrib['codeListValue'] = 'Latest Creation'
最后,我们将结果保存到文件
tree.write("output1.xml")
修改1
在这里,我们导航到已经找到的需要改变的目标[1]的cousin1(gco:Date):
t1 = targets[1]
parent1 = t1.getparent()
date1 = parent1.getprevious()
cousin1 = date1.getchildren()
len(cousin1) #1
cousin1[0].text #'1900-01-01'
# change the date
cousin1[0].text = '2017-5-3'
# again, write the result
tree.write("out456.xml")