2013-01-17 26 views
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>",然後使用正則表達式查找的文件中<address>.*</address>下一個實例,然後回去與*那是<address>標籤之間更換<name>標籤之間的?

每個點的<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 

UPDATE:在原來的服務(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次)。

+7

[Nokogiri](http://nokogiri.org/)。 – harbichidian

+2

使用XML解析器來處理XML,就像echoback所建議的一樣。 – nhahtdh

+1

謝謝,我不知道這樣的事情存在。現在閱讀文檔 - 看起來Nokogiri會有解決方案。我會在這裏更新,如果我找到一個。 –

回答

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> 
+0

我試着運行這個,它沒有錯誤地執行,但在文檔中似乎沒有改變。然後,我按照以下方式對其進行了修改,以查看代碼塊是否正在運行: –

+0

您是否輸出了新的文檔?嘗試'放入doc'。 –

+0

請參閱上面的更新,顯示我運行的代碼和結果。 –

3

的工作已經爲你做了解析/生成幾乎任何語言的KML文件。我懷疑這人會爲你工作:https://github.com/schleyfox/ruby_kml

UPDATE

有沒有實際使用,我想確認一下我的建議上述庫 - 看起來像所有的輔助功能是否有用於創建KML文件,但會仍然要求您使用XML解析器來加載一個。我仍然認爲這比使用XML解析器處理你的KML更好(儘管這肯定也能正常工作),但你也可以看看支持KML輸入和輸出的http://georuby.rubyforge.org/georuby-doc/index.html

UPDATE 2 - 爲後代添加。

把一些更多的思考進入我的回答,我對這樣的問題,默認的建議是:

  1. 的KML解析爲對象
  2. 糾正錯誤
  3. 重新生成KML

我的推理是這樣的應該不容易打亂輸出,如果你最終開始做更多的KML操縱你ar那裏已經有90%的路了。

這就是說,在您的具體情況下,您只需對已知數據進行更改,@Mark Thomas的方法將提供更快,更低代碼開銷的解決方案。

+0

儘管我大體上同意KML解析器/生成器比用XML解析器手動生成KML解析器/生成器要好,但我不確定KML解析器能否解決手頭的數據質量問題。 –

+0

我的方法是使用georuby庫將KML解析爲對象,迭代列表以更正數據問題,然後輸出結果。這就是說,按照你的規劃,這是一個非常簡單的XPath解決方案,這可能是矯枉過正的,直到你需要或想要進行其他更改(也許應用條件式等) – Matthew

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。

相關問題