2012-07-13 2 views
3

제목이 혼란 스럽다면 유감입니다. 2 개의 XML 파일을 비교하는 Python 스크립트를 작성했습니다. 두 파일 모두에서 ID가 다른 파일의 ID와 동일한 데이터가 있습니다.두 개의 XML 파일을 비교하고 그 중 하나의 요소를 업데이트하십시오.

예.

소스 파일 :

<id>123456</id> 
    <data>blabla</data> 
     ......some other data...... 
    <id>abcde</id> 
    <data>gfkgjk</data> 
     ......some more data.......... 

대상 파일 :

<id>123456</id> 
    <data> </data> 
     ......some other data...... 
    <id>ghijk</id> 
    <data>gfkgjk</data> 
     ......some more data.......... 

위의 예제가 아닌 대상 파일에 또한 소스 파일에있는 모든 ID 년대에서 볼 수 있듯이. 또한 2 개의 데이터 그룹이 동일한 ID를 가지고 있더라도 하나는 "데이터"태그가 채워져 있고 다른 하나는 그렇지 않습니다.

내 프로그램은 소스 파일을보고 데이터 태그 사이의 ID와 텍스트를 추출합니다. 그런 다음 대상 파일을 조사하고 동일한 ID와 빈 데이터 태그 (위의 예와 같이)가있는 데이터가 있으면이 빈 태그에 소스 파일의 정보를 채 웁니다. ID와 데이터 정보를 제외하고 두 XML은 완전히 다르기 때문에 소스 파일을 보관할 수는 없습니다.

오른쪽, 데이터 태그 사이의 ID와 정보를 추출 할 수있었습니다. 이제 ID를 비교하고 빈 데이터 정보가 있으면이를 대체하는 함수를 작성하려고합니다. 그러나 파이썬과 함수에 익숙하지 않고 도움이 필요합니다. 여기 내 함수가 모습입니다 :

def replace_empty_data(): 
    for x in xmlData_id_source: 
     if xmlData_id_source==xmlData_id_target: 
      target = re.sub(xmlData_2,xmlData,target) 
     return target 
    file_target.close() 

아마 기능에서 누락로드됩니다있다, 그러나 나는 무엇을 모른다. 그것은 나에게 어떤 오류도주지 않고 단순히 작동하지 않습니다. x를 제외한 변수는 코드의 이전 부분에서 정의되었으므로 이것은 문제가되지 않습니다.

xmlData_id_source는 xmlData_id_target가 xmlData_2가 입력

감사 소스 파일의 데이터 정보를 대상 파일 XMLDATA에서 데이터 정보이다 대상 파일의 ID 인 소스 파일의 ID 그래서 멀리,하지만 난 여전히 프로그래밍에 대한 단서가없는 사람을 위해 쉽게 이해할 수있는 방법을 찾고 있습니다 ... 나는 파일을 구문 분석하기 위해 minidom을 사용했고 추가 라이브러리를 가져오고 설치하지 않고 그것을 사용하고 싶습니다.

답변

2

XML 파서를 사용해야합니다. ElementTree을보십시오.

정규 표현식이나 문자열 대체를 사용하지 마십시오.

+0

나는 괜찮 았던 Minidom을 사용하고 있습니다. 남은 유일한 질문은 데이터를 추출한 후이 비교 함수를 작성하는 방법입니다. – Kaly

1

나는 좋은 성능과 기본 ElementTree가 지원하지 않는 XPATH와 같은 추가 기능이있는 lxml을 사용합니다. 여기에 내가 할 줄 것입니다 다음 data 노드가 id 하나에 캡슐화되지

>>> source = """<root> 
    <tag> 
     <id>123456</id> 
     <data>blabla</data> 
    </tag> 
    <tag> 
     <id>abcde</id> 
     <data>gfkgjk</data> 
    </tag> 
</root>""" 
>>> target = """<root> 
    <tag> 
     <id>123456</id> 
     <data> </data> 
    </tag> 
    <tag> 
     <id>ghijk</id> 
     <data>gfkgjk</data> 
    </tag> 
</root>""" 

때문에, 나는 그들이 모두 어딘가 root 아래 인하는 tag 하나에 있다고 가정한다.좋아, 첫째 부분은 id s의 DICT을 얻는 것을 목표로하고 자신은 data 해당 :

>>> root = etree.fromstring(source) 
>>> for tag in root.findall('tag'): 
    id_ = tag.find('id') 
    data = tag.find('data') 
    id_dict[id_.text] = data.text 


>>> id_dict 
{'123456': 'blabla', 'abcde': 'gfkgjk'} 

지금이 DICT에 업데이트 대상 감사 :

>>> root = etree.fromstring(target) 
>>> for tag in root.findall('tag'): 
    id_ = tag.find('id') 
    data = tag.find('data') 
    if data.text.strip() == '': 
     data.text = id_dict[id_.text] 


>>> print etree.tostring(root) 
<root> 
    <tag> 
     <id>123456</id> 
     <data>blabla</data> 
    </tag> 
    <tag> 
     <id>ghijk</id> 
     <data>gfkgjk</data> 
    </tag> 
</root> 

당신은 당신의 실제에 해당 솔루션을 적용해야 XML 구조와 그 좋은해야합니다!

+0

감사합니다. 할 일이 편리하다고 생각합니다. 방금 Python 내부 도구를 사용할 수있는 방법이 있기를 바랬습니다. 코드가 프로그램을 실행하기 전에 물건을 많이 설치하는 것에 익숙하지 않은 사람들을 위해 회사에서 배포되기 때문입니다! Mhhh ... 어쨌든, 시도해 볼 것입니다! 감사합니다 :) – Kaly

+0

글쎄, ElementTree와 lxml은 매우 기본적인 기능을 사용했기 때문에 비슷합니다 ('findall','find','.text' ...). 여러분은 그것을 그대로 사용할 수있는 기회가 있습니다. 작은 적응 노력. – Emmanuel

+0

나는 아직도 이것에 대해 머리를 쓰려고 노력하고있다. 내장 된 etree에 코드를 조정하려고했지만 내 문제는 "id_dict"가 정의되지 않았다는 오류가 발생한다는 것입니다. lxml에 특정한 id_dict [id_.text] 것입니까? – Kaly

관련 문제