Как заменить значения узлов в XML на Python - PullRequest
1 голос
/ 23 ноября 2011

Я новичок в Python.Теперь мне нужно заменить несколько значений в XML-файле на Python.Пример фрагмента XML:

<gmd:extent>
    <gmd:EX_Extent>
      <gmd:description gco:nilReason="missing">
        <gco:CharacterString />
      </gmd:description>
      <gmd:geographicElement>
        <gmd:EX_GeographicBoundingBox>
          <gmd:westBoundLongitude>
            <gco:Decimal>112.907</gco:Decimal>
          </gmd:westBoundLongitude>
          <gmd:eastBoundLongitude>
            <gco:Decimal>158.96</gco:Decimal>
          </gmd:eastBoundLongitude>
          <gmd:southBoundLatitude>
            <gco:Decimal>-54.7539</gco:Decimal>
          </gmd:southBoundLatitude>
          <gmd:northBoundLatitude>
            <gco:Decimal>-10.1357</gco:Decimal>
          </gmd:northBoundLatitude>
        </gmd:EX_GeographicBoundingBox>
      </gmd:geographicElement>
    </gmd:EX_Extent>
  </gmd:extent>

Я хочу заменить эти десятичные значения, т. Е. 112,907, указанным значением.

<gmd:extent>
    <gmd:EX_Extent>
      <gmd:description gco:nilReason="missing">
        <gco:CharacterString />
      </gmd:description>
      <gmd:geographicElement>
        <gmd:EX_GeographicBoundingBox>
          <gmd:westBoundLongitude>
            <gco:Decimal>new value</gco:Decimal>
          </gmd:westBoundLongitude>
          <gmd:eastBoundLongitude>
            <gco:Decimal>new value</gco:Decimal>
          </gmd:eastBoundLongitude>
          <gmd:southBoundLatitude>
            <gco:Decimal>new value</gco:Decimal>
          </gmd:southBoundLatitude>
          <gmd:northBoundLatitude>
            <gco:Decimal>new value</gco:Decimal>
          </gmd:northBoundLatitude>
        </gmd:EX_GeographicBoundingBox>
      </gmd:geographicElement>
    </gmd:EX_Extent>
  </gmd:extent>

Я пробовал несколько методов, но ни один из них не работал с моим предположением, что проблема заключается в префиксе пространства имен gmd и gco.

Пожалуйста, помогите мне.Заранее спасибо!

Ура, Алекс

1 Ответ

3 голосов
/ 13 января 2012

Я не смог заставить lxml обработать ваш xml без добавления поддельных объявлений пространства имен вверху, поэтому вот как выглядел ваш ввод

<gmd:extent xmlns:gmd="urn:x:y:z:1" xmlns:gco="urn:x:y:z:1">
    <gmd:EX_Extent>
        <gmd:description gco:nilReason="missing">
            <gco:CharacterString />
        </gmd:description>
        <gmd:geographicElement>
            <gmd:EX_GeographicBoundingBox>
                <gmd:westBoundLongitude>
                    <gco:Decimal>112.907</gco:Decimal>
                </gmd:westBoundLongitude>
                <gmd:eastBoundLongitude>
                    <gco:Decimal>158.96</gco:Decimal>
                </gmd:eastBoundLongitude>
                <gmd:southBoundLatitude>
                    <gco:Decimal>-54.7539</gco:Decimal>
                </gmd:southBoundLatitude>
                <gmd:northBoundLatitude>
                    <gco:Decimal>-10.1357</gco:Decimal>
                </gmd:northBoundLatitude>
            </gmd:EX_GeographicBoundingBox>
        </gmd:geographicElement>
    </gmd:EX_Extent>
</gmd:extent>

Я предположил, что у вас есть два списка, один для текущих значений и один для новых, подобных этому

старый = [112,907, 158,96, -54,7539, -10,1357] новый = [1,2,3,4] d = dict (почтовый индекс (старый, новый))

Вот полный код

#!/usr/bin/env python
import sys
from lxml import etree

def process(fname):
    f = open(fname)
    tree = etree.parse(f)
    root = tree.getroot()
    old = [112.907, 158.96, -54.7539, -10.1357]
    new = [1,2,3,4]
    d = dict(zip(old,new))
    nodes = root.findall('.//gco:Decimal', root.nsmap)
    for node in nodes:
        node.text = str(d[float(node.text)])
    f.close()
    return etree.tostring(root, pretty_print=True)

def main():
    fname = sys.argv[1]
    text = process(fname)
    outfile = open('out.xml', 'w+')
    outfile.write(text)
    outfile.close()

if __name__ == '__main__':
    main()

и вот как выглядел вывод

<gmd:extent xmlns:gmd="urn:x:y:z:1" xmlns:gco="urn:x:y:z:1">
    <gmd:EX_Extent>
        <gmd:description gco:nilReason="missing">
            <gco:CharacterString/>
        </gmd:description>
        <gmd:geographicElement>
            <gmd:EX_GeographicBoundingBox>
                <gmd:westBoundLongitude>
                    <gco:Decimal>1</gco:Decimal>
                </gmd:westBoundLongitude>
                <gmd:eastBoundLongitude>
                    <gco:Decimal>2</gco:Decimal>
                </gmd:eastBoundLongitude>
                <gmd:southBoundLatitude>
                    <gco:Decimal>3</gco:Decimal>
                </gmd:southBoundLatitude>
                <gmd:northBoundLatitude>
                    <gco:Decimal>4</gco:Decimal>
                </gmd:northBoundLatitude>
            </gmd:EX_GeographicBoundingBox>
        </gmd:geographicElement>
    </gmd:EX_Extent>
</gmd:extent>
...