この要素を含む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
ファイルを1行ずつ処理せずに全体的に処理し、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>