
요소가 포함된 KML 파일에서 모든 위치표시를 제거하고 싶습니다 <tessellate>
. 다음 블록은전적으로제거됨:
<Placemark>
<styleUrl>#m_ylw-pushpin330</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
0.0000000000000,0.0000000000000,0 0.0000000000000,0.0000000000000,0
</coordinates>
</LineString>
</Placemark>
나는 탐욕스럽지 않은 Perl 정규식을 시도했지만 운이 없었습니다 (많은 것들이 첫 번째와 함께 제거되었습니다 <Placemark>
).
sed -r ':a; N; $!ba; s/\n\t*//g' myplaces.kml |
perl -pe 's|<Placemark>.*?<tessellate>.*?</Placemark>||g'
나는 XML 파서가 갈 길이라고 생각하지만 xmlstarlet에 대한 문서를 읽었지만 아무데도 얻지 못했습니다. 따라서 xmlstarlet, python 등의 모든 솔루션도 환영합니다!
답변1
와 함께 xmlstarlet
:
xmlstarlet ed -d '//Placemark[.//tessellate]' < myplaces.kml
그리고 kml
네임스페이스를 사용하므로 이를 먼저 정의해야 합니다(참조: xmlstarlet 문서)
xmlstarlet ed -N 'ns=http://www.opengis.net/kml/2.2' -d '//ns:Placemark[.//ns:tessellate]'
를 사용하면 perl
파일을 한 줄씩 처리하지 않고 전체적으로 처리하고 s
에 플래그를 추가해야 합니다 s///
. 그런 다음에도 탐욕스럽지 않은 일치가 있더라도 다음 이후에 발생하는 첫 번째 항목부터 <Placemark>
다음 항목 까지 여전히 일치합니다 . 따라서 다음과 같이 작성해야 합니다.</Placemark>
<tessellate>
perl -0777 -pe 's|(<Placemark>.*?</Placemark>)|
$1 =~ /<tessellate>/?"":$1|gse'
답변2
이 테스트 파일이 주어지면:
start
<Placemark>
<tessellate>1</tessellate>
</Placemark>
middle1
<Placemark>
</Placemark>
middle2
<Placemark>
<tessellate>1</tessellate>
</Placemark>
end
당신 perl -0 -pe 's|<Placemark>.*?<tessellate>.*?</Placemark>||gs'
이 제안한 대로라면 너무 많이 제거될 것입니다:
start
middle1
end
이는 정규 표현식이 앞으로만 기대하기 때문입니다. 시작 태그를 찾고, 첫 번째 테셀레이트 태그부터 다음 종료 태그까지 모든 것을 가져옵니다. 불행히도 더 많은 시작 태그를 소비하더라도 상관하지 않습니다 ...
정규 표현식을 사용하려면 각 블록을 자체적으로 처리해야 합니다.
perl -0 -pe 's|<Placemark>.*?</Placemark>|$&=~/<tessellate>/?"":$&|gse'
이렇게 하면 원하는 결과를 얻을 수 있습니다.
답변3
표준 모듈과 함께 Python(2.7) 사용:
파일 test.xml
:
<Container>
<Placemark>
<KeepMe/>
</Placemark>
<Placemark>
<styleUrl>#m_ylw-pushpin330</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
0.0000000000000,0.0000000000000,0 0.0000000000000,0.0000000000000,0
</coordinates>
</LineString>
</Placemark>
</Container>
그리고 프로그램은:
#! /usr/bin/env python
from __future__ import print_function # works on 2.x and 3.x
from lxml import etree
file_name = 'test.xml'
root = etree.parse(file_name)
for element in root.iterfind('.//Placemark'):
if(element.find('.//tessellate')) is not None:
element.getparent().remove(element)
print(etree.tostring(root))
출력으로 제공됩니다 :
<Container>
<Placemark>
<KeepMe/>
</Placemark>
</Container>