1

BatchGeo を使用してスプレッドシートからマップを作成し、次に示す KML データをダウンロードしました。

<Placemark>
  <name>?</name>
    <Snippet></Snippet>
    <description><![CDATA[]]></description>
    <styleUrl>#style75</styleUrl>
    <address>1234 Example St Denver, CO 80221</address>
    <Point>
      <coordinates>-121.879364,37.815151,0.000000</coordinates>
    </Point>
</Placemark>

Google マップに再度インポートすると、ポイントは正しい住所/座標に配置されますが、左側のサイドバーの各ピンの横にある名前/説明には「?」しか表示されません。アドレスを表示する代わりに。

正規表現を使用して各 を検索し"<name>?</name>"、次に正規表現を使用してファイル内の の NEXT インスタンスを検索し、<address>.*</address>戻ってタグ間の をタグ?間の に置き換えます。<name>*<address>

各ポイントのタグ間にコード ブロックがあり<Placemark>、合計で数百のポイントがあります。

これが私がこれまでに持っているビットとピースです:

newkml = File.open( 'Newkml.txt', 'w' )

def process_line(x)
  unless x == "<name>?</name>"
    # just return the original line
  else
    # Find the next instance of /<address>(.*)<\/address>/
    # Go to the original line
    # Replace it with "<name>#{$1}</name>"
  end
end

File.foreach('Whatever.kml'){|line|} do line.process_line
# Make a new file, copy over all of the lines that aren't <name>?</name>,
# and fix the name lines using the method above

更新: 元のサービス (BatchGeo) 内に、どの情報をどの KML(XML) タグ内に入れるかを設定するオプションがあるため、新しいマップを作成して、問題が最初から発生しないようにしました。この種の操作に将来使用できるツールを紹介してくれた人に感謝します。

更新 2: Mark Thomas のソリューションを試しています。私が実行したコードは次のとおりです。

require 'rubygems'
require 'nokogiri'

doc = Nokogiri::XML("whatever.xml")

edits = 0

doc.xpath("//name").each do |name|
  if name.content == "?"
    name.content = name.xpath("following-sibling::address").text
    edits +=1
  end
end

puts( doc.inspect )
puts( "edits: #{edits}" )
puts doc

これにより、次の出力が得られます。

#<Nokogiri::XML::Document:0xfe0064 name="document>
edits: 0
<?xml version="1.0"?>

追加したeditsテスト コードが想定どおりに機能する場合、if name.content == "?"ブロックが 0 回実行されたことを示しているようです (意図したよりも約 130 回少ない)。

4

3 に答える 3

3

ほぼすべての言語でKMLファイルを解析/生成するための作業が完了しました。これはあなたのために働くと思います:https ://github.com/schleyfox/ruby_kml

アップデート

上記のライブラリを実際に使用していないので、推奨事項を確認したいと思います。KMLファイルを作成するためのすべてのヘルパー関数があるように見えますが、それでもXMLパーサーを使用してロードする必要があります。提案されているようにXMLパーサーを使用してKMLを操作するよりも、これが優れていることをお勧めします(ただし、これも確実に機能します)が、 http: //georuby.rubyforge.org/georuby-docも参照してください。 /index.htmlは、KMLの入力と出力をサポートします。

更新2-後世のために追加します。

私の答えにもう少し考えを入れると、このような問題に関する私のデフォルトの推奨事項は次のとおりです。

  1. KMLをオブジェクトに解析します
  2. エラーを修正する
  3. KMLを再生成する

私の考えでは、これは出力をゴミ箱に捨てる傾向が少ないはずであり、最終的にKMLの操作をさらに開始した場合、すでに90%の道のりになっています。

これらすべてが、特定のケースでは、既知のデータで特定した変更のみを行うために、@ Mark Thomasによるアプローチは、より高速でコードオーバーヘッドの少ないソリューションを提供します。

于 2013-01-17T04:22:57.777 に答える
2

代わりに XML パーサーを使用することをお勧めします。これは Nokogiri コードのサンプルです。

doc = Nokogiri::XML(kml)

doc.xpath("//name").each do |name|
  if name.content == "?"
    name.content = name.xpath("following-sibling::address").text
  end
end

アップデート

アップデートによると、XML ファイルの解析で問題が発生したようです。これは有効ですか?

完全な動作例を次に示します。

require 'nokogiri'

xml = <<End
<Placemark>
  <name>?</name>
    <Snippet></Snippet>
    <description><![CDATA[]]></description>
    <styleUrl>#style75</styleUrl>
    <address>1234 Example St Denver, CO 80221</address>
    <Point>
      <coordinates>-121.879364,37.815151,0.000000</coordinates>
    </Point>
</Placemark>

End

doc = Nokogiri::XML(xml)

doc.xpath("//name").each do |name|
  if name.content == "?"
    name.content = name.xpath("following-sibling::address").text
  end
end

puts doc

出力:

<?xml version="1.0"?>
<Placemark>
  <name>1234 Example St Denver, CO 80221</name>
    <Snippet/>
    <description/>
    <styleUrl>#style75</styleUrl>
    <address>1234 Example St Denver, CO 80221</address>
    <Point>
      <coordinates>-121.879364,37.815151,0.000000</coordinates>
    </Point>
</Placemark>
于 2013-01-17T03:01:39.913 に答える
0

これを使ってみましょう:

require 'nokogiri'

doc = Nokogiri::XML::DocumentFragment.parse(<<EOT)
<Placemark>
  <name>?</name>
  <Snippet></Snippet>
  <description><![CDATA[]]></description>
  <styleUrl>#style75</styleUrl>
  <address>1234 Example St Denver, CO 80221</address>
  <Point>
    <coordinates>-121.879364,37.815151,0.000000</coordinates>
  </Point>
</Placemark>
EOT

doc.search('Placemark').each do |placemark|
  name = placemark.at('name')
  address = placemark.at('address')
  name.content = address.text
end

puts doc.to_xml

どの出力:

<Placemark>
  <name>1234 Example St Denver, CO 80221</name>
  <Snippet/>
  <description><![CDATA[]]></description>
  <styleUrl>#style75</styleUrl>
  <address>1234 Example St Denver, CO 80221</address>
  <Point>
    <coordinates>-121.879364,37.815151,0.000000</coordinates>
  </Point>
</Placemark>

無関係なコンテンツを追加しないように、ドキュメントフラグメントを使用しました。通常は、通常のドキュメントを使用しNokogiri::XMLてドキュメントを解析します。

複数の<Placemark>タグがあり、それsearchが繰り返されてNodeSetが返されると想定しています。

于 2013-01-23T02:50:01.653 に答える