我使用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>
的NEXT实例,然后返回并替换?
之间的<name>
{1}}标记*
标记之间的<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次)。
答案 0 :(得分:3)
您已经完成了以几乎任何语言解析/生成KML文件的工作。我怀疑这个会对你有用:https://github.com/schleyfox/ruby_kml
更新
如果没有实际使用上面的库我想确认我的建议 - 看起来所有的帮助函数都用于创建KML文件,但仍然需要使用XML解析器来加载一个。我仍然建议这比使用建议的XML解析器操作KML更好(尽管这肯定也可以正常工作),但您可能还想查看支持KML输入和输出的http://georuby.rubyforge.org/georuby-doc/index.html。
更新2 - 为子孙后代添加内容。
在我的回答中加入一些思考,我对这类问题的默认建议是:
我的理由是应该不太容易破坏输出,如果你最终开始对KML进行更多的操作,那么你已经有90%了。
所有这些都说明,在您的具体情况下,只做出您在已知数据上识别的更改,@ Mark Thomas的方法将提供更快,更低的代码开销解决方案。
答案 1 :(得分: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>
答案 2 :(得分: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。