2012-01-30 2 views
5

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

<?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) 

--- Update 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'

--- ОРИГИНАЛ POST ---

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

Так, например, я хочу, чтобы заменить следующий код 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],

+1

См. Http://stackoverflow.com/a/1732454/383402 – Borealid

+0

спасибо ... Я не пытаюсь написать XML-файл с нуля. Я просто хочу заменить фрагменты текста в заданных атрибутах на основе ввода из дугогасящего модуля. – GeorgeC

+1

Итак, когда он производит вывод, который выглядит как ' 8097970', ваше регулярное выражение будет обрабатывать его? – Borealid

ответ

2

Использование данных тегов (ов)

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-документ. Вы можете легко адаптировать код для своих нужд.

+0

Спасибо, но я получаю следующее ... >> path = os.getcwd() >> tree = et.parse (path) Traceback (последний последний звонок): Файл «C: \ Program Files (x86) \ Wing IDE 101 4.0 \ src \ debug \ tserver \ _sandbox.py", строка 1, в # Используется внутренне для отладочной песочницы под внешним интерпретатором Файл «C: \ Python26 \ ArcGIS10.0 \ Lib \ xml \ etree \ ElementTree.py», строка 862, в парсе tree.parse (источник, парсер) Файл «C: \ Python26 \ ArcGIS10.0 \ Lib \ xml \ etree \ ElementTree.py ", строка 579, в разделе source = open (source," rb ") IOError: [ Errno 13] Permission denied: 'L: \\ Data_Admin \\ QA \\ Metadata_python_toolset \\ training' – GeorgeC

+0

Пожалуйста, ОТКАЗЫВАЙТЕ мой предыдущий комментарий. Он отлично работает, когда путь является фактическим xml-файлом. Что бы вы сделали с повторением тегов, как в третьем примере - '', где имя формы повторяется, но nondig уникален. – GeorgeC

+0

Если я правильно понял, у вас есть несколько s, которые являются прямыми детьми уникальных узлов ? Затем вы можете использовать такой xpath .//nondig/formname, чтобы получить s. Вы можете либо промахнуться в дереве, либо проверить родителя перед заменой значения или даже лучше переписать свой xpath с помощью уникального attr родителя (возможно, идентификатора?), Чтобы s были сгруппированы по . – Aleyna

0

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

1

Если вы имеете дело с действующим XML, используйте XPath, чтобы найти интересующие узлы и apiElementTree для управления узлом.

Например, ваш 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

спасибо. Это похоже на правильный путь, и я просто просматриваю http://www.w3schools.com/xpath/ – GeorgeC

Смежные вопросы