将KML文件转换为CSV,并在rgdal和sf包以及Python中出现错误

将KML文件转换为CSV,并在rgdal和sf包以及Python中出现错误,python,r,kml,sf,rgdal,Python,R,Kml,Sf,Rgdal,我在用R和Python解析这个KML文件的层时遇到困难。我已经包括了一个从我的Dropbox下载文件的链接。此文件最初与我共享。然而,有人告诉我文件的来源是,但我不知道如何找到它或找到它 我想要的是提取所有层,并最终将它们分离到自己的csv文件中。我想要检索的节点是名称、地址、城市、州、邮政编码。我用这个得到的最接近的是从堆栈柱 对于第一次尝试,我的代码如下所示: library(rgdal) allKmlLayers <- function(kmlfile){ lyr <- o

我在用R和Python解析这个KML文件的层时遇到困难。我已经包括了一个从我的Dropbox下载文件的链接。此文件最初与我共享。然而,有人告诉我文件的来源是,但我不知道如何找到它或找到它

我想要的是提取所有层,并最终将它们分离到自己的
csv
文件中。我想要检索的节点是名称、地址、城市、州、邮政编码。我用这个得到的最接近的是从堆栈柱

对于第一次尝试,我的代码如下所示:

library(rgdal)
allKmlLayers <- function(kmlfile){
  lyr <- ogrListLayers(kmlfile)
  mykml <- list()
  for (i in 1:length(lyr)){
    mykml[i] <- readOGR(kmlfile, lyr[i])
  }
  names(mykml) <- lyr
  return(mykml)
}

kmlfile <- "Distilleries and Hospitals.kml"
mykml <- allKmlLayers(kmlfile)
我得到了7个没有信息的0x3列表

这方面的任何帮助都将是非常好的

最后请注意,如果您最终从网站上获取了文件,请注意,在文件末尾附近有几个实例,其中R由于特殊字符而不会读取文件(至少我不会)。当使用sf函数时,错误将告诉您这是在哪里

谢谢你在这方面花时间

编辑1: 从下面留下的注释来看,该文件中的层似乎是空的。如果这是正确的,那么问题是,我将如何从这个文件中获取所需的数据并将其转换为CSV文件

编辑2: 进一步调查KML文档,似乎我的所有信息都可以在
placemark
标记(…)中找到。然而,我不确定如何提取这些数据。这是最终目标。如果这些不是层,那么如果有人能告诉我解决这个问题的方向,那就太好了。再次,我想提前感谢你的帮助

编辑3个数据摘录和Python尝试: 我已经手动操作了这个文件,从长远来看,删除了我并不真正感兴趣的所有内容。下面是该文件的一个小摘录。它列出了前三家公司

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <Folder>
      <name>Distilleries</name>
      <Placemark>
        <name>Bomb City Enterprises</name>
        <description><![CDATA[Address: 306 S Cleveland St<br>Address Line2: <br>City: Amarillo<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 79102<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
        <ExtendedData>
          <Data name="Address">
            <value>306 S Cleveland St</value>
          </Data>
          <Data name="Address Line2">
            <value/>
          </Data>
          <Data name="City">
            <value>Amarillo</value>
          </Data>
          <Data name="Location">
            <value>Alabama</value>
          </Data>
          <Data name="State_Abbrev">
            <value>AL</value>
          </Data>
          <Data name="Postal Code">
            <value>79102</value>
          </Data>
          <Data name="unnamed (1)">
            <value/>
          </Data>
          <Data name="unnamed (2)">
            <value/>
          </Data>
          <Data name="unnamed (3)">
            <value/>
          </Data>
          <Data name="Updated 2020-04-12 20:30:13.383810">
            <value/>
          </Data>
        </ExtendedData>
      </Placemark>
      <Placemark>
        <name>Cahaba Brewing Company</name>
        <address>4500 5th Ave. S building C Birmingham Alabama AL 35222</address>
        <description><![CDATA[Address: 4500 5th Ave. S<br>Address Line2: building C<br>City: Birmingham<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 35222<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
        <styleUrl>#icon-1517-0288D1</styleUrl>
        <ExtendedData>
          <Data name="Address">
            <value>4500 5th Ave. S</value>
          </Data>
          <Data name="Address Line2">
            <value>building C</value>
          </Data>
          <Data name="City">
            <value>Birmingham</value>
          </Data>
          <Data name="Location">
            <value>Alabama</value>
          </Data>
          <Data name="State_Abbrev">
            <value>AL</value>
          </Data>
          <Data name="Postal Code">
            <value>35222</value>
          </Data>
          <Data name="unnamed (1)">
            <value/>
          </Data>
          <Data name="unnamed (2)">
            <value/>
          </Data>
          <Data name="unnamed (3)">
            <value/>
          </Data>
          <Data name="Updated 2020-04-12 20:30:13.383810">
            <value/>
          </Data>
        </ExtendedData>
      </Placemark>
      <Placemark>
        <name>Redmont Distilling Company</name>
        <address>4550 5th Ave South building N Birmingham Alabama AL 35222</address>
        <description><![CDATA[Address: 4550 5th Ave South<br>Address Line2: building N<br>City: Birmingham<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 35222<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
        <styleUrl>#icon-1517-0288D1</styleUrl>
        <ExtendedData>
          <Data name="Address">
            <value>4550 5th Ave South</value>
          </Data>
          <Data name="Address Line2">
            <value>building N</value>
          </Data>
          <Data name="City">
            <value>Birmingham</value>
          </Data>
          <Data name="Location">
            <value>Alabama</value>
          </Data>
          <Data name="State_Abbrev">
            <value>AL</value>
          </Data>
          <Data name="Postal Code">
            <value>35222</value>
          </Data>
          <Data name="unnamed (1)">
            <value/>
          </Data>
          <Data name="unnamed (2)">
            <value/>
          </Data>
          <Data name="unnamed (3)">
            <value/>
          </Data>
          <Data name="Updated 2020-04-12 20:30:13.383810">
            <value/>
          </Data>
        </ExtendedData>
      </Placemark>
      <Placemark>
当我运行此操作时,我得到第一条记录,第一个地址行为1,但我也得到以下错误:

AttributeError:“非类型”对象没有属性“strip”

我相信这是因为在第一条记录中,地址2是空的。因此,我相信这实际上是试图从扩展数据中一次提取所有内容,这也不是我想要的

我遇到的真正困难是拉
字段

这是我第一次尝试XML/KML解析,因此我非常感谢您的帮助。现在我真的不知道下一步该怎么做

结束文件将是一个CSV文件,标题为:名称、地址1、地址2、城市、州、邮政编码。老实说,我也可以摆脱地址2。拥有并不重要


如果您需要进一步的澄清,请直接询问。感谢您提前的时间。

由于KML文件是XML文件,请考虑,专门用于将XML文件转换成不同的XML、HTML、甚至CSV格式的专用语言。 带有

lxml
的Python和带有
xslt
(扩展包到
xml2
)的R模块都可以运行xslt1.0脚本

XSLT(另存为.xsl,一个特殊的.xml文件)

R

library(xml2)
library(xslt)

# PARSE XML AND XSLT
doc <- read_xml('/path/toInput.kml')
style <- read_xml('/path/to/Script.xsl', package = "xslt")

# TRANSFORM NESTED INPUT INTO FLATTER OUTPUT
new_xml <- xslt::xml_xslt(doc, style)

# SAVE CSV
f <- file("/path/to/Output.csv")
    writeLines(new_xml, f)
close(f)

# BUILD DATA FRAME
final_df <- read.csv('/path/to/Output.csv')

#                         Name          Address.1  Address.2       City   State   Zip
# 1      Bomb City Enterprises 306 S Cleveland St              Amarillo Alabama 79102
# 2     Cahaba Brewing Company    4500 5th Ave. S building C Birmingham Alabama 35222
# 3 Redmont Distilling Company 4550 5th Ave South building N Birmingham Alabama 35222
库(xml2)
库(xslt)
#解析XML和XSLT

doc据我所知,文件中的层是空的,您可以建议如何从文件中获取名称、地址、城市、州和zip节点。如果它不在一个层中,那么它是如何安置的,解决这个问题的最佳方法是什么?感谢您可以使用类似于
xml2
的包来读取kml文件。是的,我也尝试过使用它。
library(sf)
kmlfile <- "Distilleries and Hospitals.kml"
mykml <- lapply(lyr, function(i) st_read(kmlfile, i))
names(mykml) <- lyr
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <Folder>
      <name>Distilleries</name>
      <Placemark>
        <name>Bomb City Enterprises</name>
        <description><![CDATA[Address: 306 S Cleveland St<br>Address Line2: <br>City: Amarillo<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 79102<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
        <ExtendedData>
          <Data name="Address">
            <value>306 S Cleveland St</value>
          </Data>
          <Data name="Address Line2">
            <value/>
          </Data>
          <Data name="City">
            <value>Amarillo</value>
          </Data>
          <Data name="Location">
            <value>Alabama</value>
          </Data>
          <Data name="State_Abbrev">
            <value>AL</value>
          </Data>
          <Data name="Postal Code">
            <value>79102</value>
          </Data>
          <Data name="unnamed (1)">
            <value/>
          </Data>
          <Data name="unnamed (2)">
            <value/>
          </Data>
          <Data name="unnamed (3)">
            <value/>
          </Data>
          <Data name="Updated 2020-04-12 20:30:13.383810">
            <value/>
          </Data>
        </ExtendedData>
      </Placemark>
      <Placemark>
        <name>Cahaba Brewing Company</name>
        <address>4500 5th Ave. S building C Birmingham Alabama AL 35222</address>
        <description><![CDATA[Address: 4500 5th Ave. S<br>Address Line2: building C<br>City: Birmingham<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 35222<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
        <styleUrl>#icon-1517-0288D1</styleUrl>
        <ExtendedData>
          <Data name="Address">
            <value>4500 5th Ave. S</value>
          </Data>
          <Data name="Address Line2">
            <value>building C</value>
          </Data>
          <Data name="City">
            <value>Birmingham</value>
          </Data>
          <Data name="Location">
            <value>Alabama</value>
          </Data>
          <Data name="State_Abbrev">
            <value>AL</value>
          </Data>
          <Data name="Postal Code">
            <value>35222</value>
          </Data>
          <Data name="unnamed (1)">
            <value/>
          </Data>
          <Data name="unnamed (2)">
            <value/>
          </Data>
          <Data name="unnamed (3)">
            <value/>
          </Data>
          <Data name="Updated 2020-04-12 20:30:13.383810">
            <value/>
          </Data>
        </ExtendedData>
      </Placemark>
      <Placemark>
        <name>Redmont Distilling Company</name>
        <address>4550 5th Ave South building N Birmingham Alabama AL 35222</address>
        <description><![CDATA[Address: 4550 5th Ave South<br>Address Line2: building N<br>City: Birmingham<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 35222<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
        <styleUrl>#icon-1517-0288D1</styleUrl>
        <ExtendedData>
          <Data name="Address">
            <value>4550 5th Ave South</value>
          </Data>
          <Data name="Address Line2">
            <value>building N</value>
          </Data>
          <Data name="City">
            <value>Birmingham</value>
          </Data>
          <Data name="Location">
            <value>Alabama</value>
          </Data>
          <Data name="State_Abbrev">
            <value>AL</value>
          </Data>
          <Data name="Postal Code">
            <value>35222</value>
          </Data>
          <Data name="unnamed (1)">
            <value/>
          </Data>
          <Data name="unnamed (2)">
            <value/>
          </Data>
          <Data name="unnamed (3)">
            <value/>
          </Data>
          <Data name="Updated 2020-04-12 20:30:13.383810">
            <value/>
          </Data>
        </ExtendedData>
      </Placemark>
      <Placemark>
import xml.etree.ElementTree as et

doc = et.parse(filename)
nmsp = '{http://www.opengis.net/kml/2.2}'

name = []
address1 = []

for pm in doc.iterfind('.//{0}Placemark'.format(nmsp)):
    print(pm.find('{0}name'.format(nmsp)).text)
    name.append(pm.find('{0}name'.format(nmsp)).text)
    for adr1 in pm.iterfind('{0}ExtendedData//{0}value'.format(nmsp)):
        address1.append(adr1.text.strip().replace('\n',''))
        print(adr1.text.strip().replace('\n',''))

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:doc="http://www.opengis.net/kml/2.2">
  <xsl:output indent="yes" method="text" encoding="UTF-8"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/doc:kml">
    <xsl:copy>
      <xsl:text>Name,Address 1,Address 2,City,State,Zip&#xa;</xsl:text>
      <xsl:apply-templates select="descendant::doc:Placemark"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="doc:Placemark">
    <xsl:copy>
      <xsl:value-of select="concat(doc:name, ',',
                                   doc:ExtendedData/doc:Data[@name='Address'], ',',
                                   doc:ExtendedData/doc:Data[@name='Address Line2'], ',',
                                   doc:ExtendedData/doc:Data[@name='City'], ',',
                                   doc:ExtendedData/doc:Data[@name='Location'], ',',
                                   doc:ExtendedData/doc:Data[@name='Postal Code'])"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
import lxml.etree as et

# INPUT XML AND XSL SOURCES
xml = et.parse('/path/to/Input.kml')
xsl = et.parse('/path/to/Script.xsl')

# RUN TRANSFORMATION
transformer = et.XSLT(xsl)
new_xml = transformer(xml)

# PRINT TO CONSOLE
print(new_xml)
# Name,Address 1,Address 2,City,State,Zip
# Bomb City Enterprises,306 S Cleveland St,,Amarillo,Alabama,79102
# Cahaba Brewing Company,4500 5th Ave. S,building C,Birmingham,Alabama,35222
# Redmont Distilling Company,4550 5th Ave South,building N,Birmingham,Alabama,35222

# SAVE TO FILE
with open('/path/to/Output.csv', 'wb') as f:
   f.write(new_xml)
library(xml2)
library(xslt)

# PARSE XML AND XSLT
doc <- read_xml('/path/toInput.kml')
style <- read_xml('/path/to/Script.xsl', package = "xslt")

# TRANSFORM NESTED INPUT INTO FLATTER OUTPUT
new_xml <- xslt::xml_xslt(doc, style)

# SAVE CSV
f <- file("/path/to/Output.csv")
    writeLines(new_xml, f)
close(f)

# BUILD DATA FRAME
final_df <- read.csv('/path/to/Output.csv')

#                         Name          Address.1  Address.2       City   State   Zip
# 1      Bomb City Enterprises 306 S Cleveland St              Amarillo Alabama 79102
# 2     Cahaba Brewing Company    4500 5th Ave. S building C Birmingham Alabama 35222
# 3 Redmont Distilling Company 4550 5th Ave South building N Birmingham Alabama 35222