使用python和lxm访问重复的特定xml元素

2024-10-01 00:22:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个如下所示的xml文件

  <_gmd_citation>
    <_gmd_CI_Citation>
      <_gmd_title xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
          <_gco_CharacterString>Conservation Areas</_gco_CharacterString>
        </_gmd_title>
      <_gmd_alternateTitle _gco_nilReason="missing" />
      <_gmd_date>
        <_gmd_CI_Date>
          <_gmd_date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
              <_gco_Date>2018-07-24</_gco_Date>
            </_gmd_date>
          <_gmd_dateType>
            <_gmd_CI_DateTypeCode codeListValue="publication" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" />
          </_gmd_dateType>
        </_gmd_CI_Date>
      </_gmd_date>
      <_gmd_date>
        <_gmd_CI_Date>
          <_gmd_date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
              <_gco_Date>2013-11-15</_gco_Date>
            </_gmd_date>
          <_gmd_dateType>
            <_gmd_CI_DateTypeCode codeListValue="creation" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" />
          </_gmd_dateType>
        </_gmd_CI_Date>
      </_gmd_date>
      <_gmd_date>
        <_gmd_CI_Date>
          <_gmd_date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
              **<_gco_Date>2016-11-11</_gco_Date>**
            </_gmd_date>
          <_gmd_dateType>
            <_gmd_CI_DateTypeCode codeListValue="**revision**" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" />
          </_gmd_dateType>
        </_gmd_CI_Date>
      </_gmd_date>
      <_gmd_identifier>
        <_gmd_RS_Identifier>
          <_gmd_authority _gco_nilReason="missing" />
          <_gmd_code>
            <_gco_CharacterString>0000</_gco_CharacterString>
          </_gmd_code>
          <_gmd_codeSpace xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
              <_gco_CharacterString>abc</_gco_CharacterString>
            </_gmd_codeSpace>
        </_gmd_RS_Identifier>
      </_gmd_identifier>
    </_gmd_CI_Citation>

我想做的是,如果codeListValue=='revision',则更改cu gco_日期。在

我遇到的问题是元素“gco”date出现了多次。 我可以像这样迭代元素

^{pr2}$

但我似乎无法指定要更改的标记。 最好的办法是什么?在


Tags: opengiscihttpdatenetwwwgcoxmlns
2条回答

您所面临的“问题”不是存在多个_gco_Date元素,而是您的任务不是找到一个元素并对同一个元素执行某些操作。虽然您没有明确说明这一点(也不清楚文档可能有哪些可能的结构变化),但我可以将您的目标表述为:

find and modify an element with tag _gco_Date that has a parent (tagged _gmd_date?) which in turn has a sibling with a child having _gmd_CI_DateTypeCode tag if and only if that latter tag has an attribute 'codeListValue' equal to 'revision'.

如果这是您需要的(或类似的),那么您必须使用文档结构,而不是简单地迭代元素,而不考虑元素的位置。element tree对象为您提供了实现此目标所需的一切(您可以获得父对象、子对象列表、同级列表等)。在

这是一个可以作为基础的原始示例(不是世界上最好的编码,只是一个原型!)公司名称:

import lxml.etree
p=lxml.etree.ETCompatXMLParser()
p.feed(open("test.xml").read())
d=p.close()

def dt_rev(e):
   """this finds if 'e' has a child node with the right tag and attribute value codeListValue == revision """
   for c in e.iterchildren():
     if c.tag == "_gmd_CI_DateTypeCode" and c.attrib['codeListValue'] == 'revision':
       return True
   return False

for e in d.getiterator():
    if e.tag == "_gco_Date":
        p = e.getparent()
        for s in p.itersiblings():
            if dt_rev(s):
                print ("found it!", e.text)
                # add code here to modify the element "e" as needed

不要迭代元素并测试标记名和属性值,请尝试使用XPath。在

通过使用predicate[ ]),我们可以轻松地选择我们需要的东西,而无需迭代。在

示例。。。在

**根据评论中的讨论更新了名称空间。**

XML输入(输入.xml)在

<gmd:citation xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco">
    <gmd:CI_Citation>
        <gmd:title xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
            <gco:CharacterString>Conservation Areas</gco:CharacterString>
        </gmd:title>
        <gmd:alternateTitle gco:nilReason="missing" />
        <gmd:date>
            <gmd:CI_Date>
                <gmd:date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:Date>2018-07-24</gco:Date>
                </gmd:date>
                <gmd:dateType>
                    <gmd:CI_DateTypeCode codeListValue="publication" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" />
                </gmd:dateType>
            </gmd:CI_Date>
        </gmd:date>
        <gmd:date>
            <gmd:CI_Date>
                <gmd:date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:Date>2013-11-15</gco:Date>
                </gmd:date>
                <gmd:dateType>
                    <gmd:CI_DateTypeCode codeListValue="creation" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" />
                </gmd:dateType>
            </gmd:CI_Date>
        </gmd:date>
        <gmd:date>
            <gmd:CI_Date>
                <gmd:date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:Date>2016-11-11</gco:Date>
                </gmd:date>
                <gmd:dateType>
                    <gmd:CI_DateTypeCode codeListValue="revision" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" />
                </gmd:dateType>
            </gmd:CI_Date>
        </gmd:date>
        <gmd:identifier>
            <gmd:RS_Identifier>
                <gmd:authority gco:nilReason="missing" />
                <gmd:code>
                    <gco:CharacterString>0000</gco:CharacterString>
                </gmd:code>
                <gmd:codeSpace xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:CharacterString>abc</gco:CharacterString>
                </gmd:codeSpace>
            </gmd:RS_Identifier>
        </gmd:identifier>
    </gmd:CI_Citation>
</gmd:citation>

Python

^{pr2}$

输出

<gmd:citation xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco">
    <gmd:CI_Citation>
        <gmd:title xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
            <gco:CharacterString>Conservation Areas</gco:CharacterString>
        </gmd:title>
        <gmd:alternateTitle gco:nilReason="missing"/>
        <gmd:date>
            <gmd:CI_Date>
                <gmd:date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:Date>2018-07-24</gco:Date>
                </gmd:date>
                <gmd:dateType>
                    <gmd:CI_DateTypeCode codeListValue="publication" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode"/>
                </gmd:dateType>
            </gmd:CI_Date>
        </gmd:date>
        <gmd:date>
            <gmd:CI_Date>
                <gmd:date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:Date>2013-11-15</gco:Date>
                </gmd:date>
                <gmd:dateType>
                    <gmd:CI_DateTypeCode codeListValue="creation" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode"/>
                </gmd:dateType>
            </gmd:CI_Date>
        </gmd:date>
        <gmd:date>
            <gmd:CI_Date>
                <gmd:date xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:Date>NEW VALUE</gco:Date>
                </gmd:date>
                <gmd:dateType>
                    <gmd:CI_DateTypeCode codeListValue="revision" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode"/>
                </gmd:dateType>
            </gmd:CI_Date>
        </gmd:date>
        <gmd:identifier>
            <gmd:RS_Identifier>
                <gmd:authority gco:nilReason="missing"/>
                <gmd:code>
                    <gco:CharacterString>0000</gco:CharacterString>
                </gmd:code>
                <gmd:codeSpace xmlns:gml="http://www.opengis.net/gml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
                    <gco:CharacterString>abc</gco:CharacterString>
                </gmd:codeSpace>
            </gmd:RS_Identifier>
        </gmd:identifier>
    </gmd:CI_Citation>
</gmd:citation>

重要信息:确保两个名称空间uri(http://www.isotc211.org/2005/gmd和{})与xml中的内容完全匹配。注释中的uri是自动格式化的,因此“http://”部分不会显示。在

另外,see here获取有关在lxml中对名称空间使用XPath的更多信息。在

相关问题 更多 >