이 요소가 포함된 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>