【问题标题】:Set new value on attributes in a namespace为命名空间中的属性设置新值
【发布时间】:2017-03-29 09:34:25
【问题描述】:

我有这个 xml(它是更扩展的一部分),我正在使用 python 和 lxml 进行解析

<om:OM_Observation gml:id="observation">
 <gml:description>Wind Speed</gml:description>     
 <om:phenomenonTime xlink:href="#phenomenonTime"/>
 <om:resultTime xlink:href="#phenomenonTime"/>
 <om:procedure xlink:href="procedure"/>
 <om:observedProperty xlink:href="WS_5min_avg"/>
 <om:featureOfInterest xlink:href="#FOI"/>
 <om:result xsi:type="gml:MeasureType" uom="m/s">568</om:result>
</om:OM_Observation>

我能够获取标签中的文本值并更改其值并更新文件 data.xml:

from lxml import etree
data='data.xml'
data_tree = etree.parse(data)
root = data_tree.getroot()
nsmap = {'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xlink': 'http://www.w3.org/1999/xlink',  'gml': 'http://www.opengis.net/gml/3.2',  'om': 'http://www.opengis.net/om/2.0'}

result=data_tree.xpath("//om:OM_Observation/om:result", namespaces=nsmap)
result[0].text="114"    
etree.ElementTree(root).write(data, xml_declaration=True, encoding='utf-8', method="xml", pretty_print=True)

我想做的是更改属性的值并更新xml文件。 我正在尝试类似的方法,但它不起作用。我能够得到属性的值:

 featureOfInterest_attr=tree.xpath("//om:featureOfInterest/@xlink:href", namespaces=nsmap)

但如果我想使用以下方法更改其值:

tree.xpath("//om:featureOfInterest/@xlink:href",namespaces=nsmap)="#newFOI"
etree.ElementTree(root).write(data, xml_declaration=True,encoding='utf-8', method='xml', pretty_print=True)

未插入新值。 我做错了什么?

【问题讨论】:

    标签: python xpath lxml


    【解决方案1】:

    您的上一个代码 sn-p 与您成功的代码有着至关重要的区别。 xpath() 返回列表,所以你必须通过索引指定列表中的哪个项目需要更新:

    result = tree.xpath("//om:featureOfInterest/@xlink:href",namespaces=nsmap)
    result[0] = "#newFOI"
    # or
    # tree.xpath("//om:featureOfInterest/@xlink:href",namespaces=nsmap)[0] = "#newFOI"
    

    显然,我们无法更新使用xpath() 直接选择的属性,因为返回值只是一个字符串列表。所以在这种情况下result[0] = ... 只更新列表的第一项的值,根本不影响源 XML 树。我们需要获取属性的父级,然后从那里更新:

    result = tree.xpath("//om:featureOfInterest",namespaces=nsmap)
    result[0].attrib['{%s}href' % nsmap['xlink']] = "#newFOI"
    

    【讨论】:

    • 嗨@har07 你是对的。感谢您的第一个建议。但是,不幸的是,我仍然无法使用新属性值更新 xml 文件。我还缺少什么吗?
    • 修改后是否将data_tree写回磁盘/文件?
    • 是的,我按照帖子 etree.ElementTree(root).write(data.xml, xml_declaration=True,encoding='utf-8', method='xml', pretty_print=真的)
    • data_tree.write(...) 怎么样?即不创建新的ElementTree
    • 嗨@har07 不幸的是,即使使用 data_tree.write(...) 它也不会改变 xml 文件的最终输出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    相关资源
    最近更新 更多