Поиск и замена нескольких строк в XML / текстовых файлах с использованием Python - PullRequest
5 голосов
/ 30 января 2012

--- Обновление 3: У меня есть скрипт для обновления необходимых данных в XML-файлы завершена, но следующий код удаляется из записанного файла. Почему это? как я могу заменить его?

<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='ANZMeta.xsl'?>

Текущий рабочий код (кроме упомянутой выше проблемы).

import os, xml, arcpy, shutil
from xml.etree import ElementTree as et 

path=os.getcwd()
arcpy.env.workspace = path

FileList = arcpy.ListFeatureClasses()
FileCount = len(FileList)
zone="_Zone"

for File in FileList:
    FileDesc_obj = arcpy.Describe(File)
    FileNm=FileDesc_obj.file
    newMetaFile=FileNm+"_BaseMetadata.xml"

    check_meta=os.listdir(path)
    if FileNm+'.xml' in check_meta:
        shutil.copy2(FileNm+'.xml', newMetaFile)
    else:
        shutil.copy2('L:\Data_Admin\QA\Metadata_python_toolset\Master_Metadata.xml', newMetaFile)
    tree=et.parse(newMetaFile)

    print "Processing: "+str(File)

    for node in tree.findall('.//title'):
        node.text = str(FileNm)
    for node in tree.findall('.//northbc'):
        node.text = str(FileDesc_obj.extent.YMax)
    for node in tree.findall('.//southbc'):
        node.text = str(FileDesc_obj.extent.YMin)
    for node in tree.findall('.//westbc'):
        node.text = str(FileDesc_obj.extent.XMin)
    for node in tree.findall('.//eastbc'):
        node.text = str(FileDesc_obj.extent.XMax)        
    for node in tree.findall('.//native/nondig/formname'):
        node.text = str(os.getcwd()+"\\"+File)
    for node in tree.findall('.//native/digform/formname'):
        node.text = str(FileDesc_obj.featureType)
    for node in tree.findall('.//avlform/nondig/formname'):
        node.text = str(FileDesc_obj.extension)
    for node in tree.findall('.//avlform/digform/formname'):
        node.text = str(float(os.path.getsize(File))/int(1024))+" KB"
    for node in tree.findall('.//theme'):
        node.text = str(FileDesc_obj.spatialReference.name +" ; EPSG: "+str(FileDesc_obj.spatialReference.factoryCode))
    print node.text
    projection_info=[]
    Zone=FileDesc_obj.spatialReference.name

    if "GCS" in str(FileDesc_obj.spatialReference.name):
        projection_info=[FileDesc_obj.spatialReference.GCSName, FileDesc_obj.spatialReference.angularUnitName, FileDesc_obj.spatialReference.datumName, FileDesc_obj.spatialReference.spheroidName]
        print "Geographic Coordinate system"
    else:
        projection_info=[FileDesc_obj.spatialReference.datumName, FileDesc_obj.spatialReference.spheroidName, FileDesc_obj.spatialReference.angularUnitName, Zone[Zone.rfind(zone)-3:]]
        print "Projected Coordinate system"
    x=0
    for node in tree.findall('.//spdom'):
        for node2 in node.findall('.//keyword'):
            print node2.text
            node2.text = str(projection_info[x])
            print node2.text
            x=x+1


    tree.write(newMetaFile)

--- Обновление 1 и 2: Благодаря Aleyna у меня есть следующий базовый код, который работает

import os, xml, arcpy, shutil
from xml.etree import ElementTree as et 

CodeString=['northbc','southbc', '<nondig><formname>']

nondig='nondigital'
path=os.getcwd()
arcpy.env.workspace = path
xmlfile = path+"\\test.xml"

FileList = arcpy.ListFeatureClasses()
FileCount = len(FileList)

for File in FileList:
    FileDesc_obj = arcpy.Describe(File)
    FileNm=FileDesc_obj.file
    newMetaFile=FileNm+"_Metadata.xml"
    shutil.copy2('L:\Data_Admin\QA\Metadata_python_toolset\Master_Metadata.xml', newMetaFile)
    tree=et.parse(newMetaFile)

    for node in tree.findall('.//northbc'):
        node.text = str(FileDesc_obj.extent.YMax)
    for node in tree.findall('.//southbc'):
        node.text = str(FileDesc_obj.extent.YMin)
    for node in tree.findall('.//westbc'):
        node.text = str(FileDesc_obj.extent.XMin)
    for node in tree.findall('.//eastbc'):
        node.text = str(FileDesc_obj.extent.XMax)        
    for node in tree.findall('.//native/nondig/formname'):
        node.text = nondig

    tree.write(newMetaFile)

Проблема заключается в работе с XML-кодом, подобным

- <spdom>
  <keyword thesaurus="">GDA94</keyword> 
  <keyword thesaurus="">GRS80</keyword> 
  <keyword thesaurus="">Transverse Mercator</keyword> 
  <keyword thesaurus="">Zone 55 (144E - 150E)</keyword> 
  </spdom>

Поскольку ключевое слово thes ... не является уникальным в <spdom>, можем ли мы обновить их в порядке значений из

FileDesc_obj.spatialReference.name

u'GCS_GDA_1994'

--- ОРИГИНАЛЬНЫЙ ПОЧТА ---

Я создаю программу для генерации файлов метаданных XML из пространственных файлов в нашей библиотеке. Я уже создал сценарии для извлечения необходимых пространственных и атрибутивных данных из файлов и создания индекса файлов на основе shp и текстового файла, но теперь я хочу записать эту информацию в базовый XML-файл метаданных, который записан в стандартах anzlic, заменив значения, хранящиеся в общих / статических элементах ...

Так, например, я хочу заменить следующий код XML

<northbc>8097970</northbc>
<southbc>8078568</southbc>

с

<northbc> GeneratedValue_[desc.extent.XMax] /<northbc>
<southbc> GeneratedValue_[desc.extent.XMax] </southbc>

Проблема в том, что число / значение между и не будет одинаковым.

Аналогично для тегов xml, таких как <title>, <nondig><formname> и т. Д. ... в последнем примере оба тега необходимо искать вместе, так как имя формы появляется несколько раз (не является уникальным).

Я использую руководство по регулярным выражениям Python [здесь] [1],

Ответы [ 3 ]

2 голосов
/ 30 января 2012

Используя приведенный выше тег (ы):

import os
import xml
from xml.etree import ElementTree as et 
path = r"/your/path/to/xml.file" 
tree = et.parse(path)
for node in tree.findall('.//northbc'):
    node.text = "New Value"
tree.write(path)

Здесь XPATH .//northbc возвращает все узлы 'northbc' в XML-документе.Вы можете легко адаптировать код под свои нужды.

1 голос
/ 30 января 2012

Если вы имеете дело с действительным XML, используйте XPath для поиска интересующих узлов и API ElementTree для управления этим узлом.

Например, ваш xpath может быть чем-то вроде '// northbc', и вы просто замените текстовый узел внутри него.

См. http://docs.python.org/library/xml.etree.elementtree.html, а также http://pypi.python.org/pypi/lxml/2.2.8 для двух разных библиотек, которые помогут вам сделать это. Поищите в Google XPath и посмотрите учебник по w3c для приличного введения в XPath (очевидно, я не могу опубликовать более двух ссылок в сообщении, или я бы тоже связал его)

0 голосов
/ 30 января 2012

Я мог бы заявить об очевидном здесь, но вы рассматривали возможность использования дерева DOM для анализа и манипулирования вашим XML?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...