Python 如何使用lmxl从KML获取元素值

Python 如何使用lmxl从KML获取元素值,python,xml,lxml,kml,Python,Xml,Lxml,Kml,我的问题与这里的问题非常相似: 以上问题的答案是使用Nokogiri来修复格式 我想知道是否有一种方法可以解决类似的问题,而不必先修改格式 如何获取dict的值,以便从下面的元素SimpleData中获取“FM2”和“FM3” 这是我的kml: <?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/km

我的问题与这里的问题非常相似:

以上问题的答案是使用Nokogiri来修复格式

我想知道是否有一种方法可以解决类似的问题,而不必先修改格式

如何获取dict的值,以便从下面的元素SimpleData中获取“FM2”和“FM3”

这是我的kml:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>Test.kml</name>
    <open>1</open>
    <Schema name="test" id="S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
        <SimpleField type="string" name="ID"> <displayName>&lt;b&gt;ID&lt;/b&gt;</displayName>
        </SimpleField>
        <SimpleField type="string" name="cname"><displayName>&lt;b&gt;cname&lt;/b&gt;</displayName>
        </SimpleField>
    </Schema>
    <Style id="falseColor01">
        <BalloonStyle>
            <text><![CDATA[<table border="0"><tr> 
            <td>b>ID</b>/td>td>$[test/ID]</td></tr>
            <tr><td><b>cname</b></td><td>$[test/cname]</td></tr>
            </table>]]></text>
        </BalloonStyle>
        <LineStyle>
            <color>ffffff00</color>
            <width>3</width>
        </LineStyle>
        <PolyStyle>
            <color>ffffff00</color>
            <colorMode>random</colorMode>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <StyleMap id="falseColor0">
        <Pair>
            <key>normal</key>
            <styleUrl>#falseColor00</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#falseColor01</styleUrl>
        </Pair>
    </StyleMap>
    <Style id="falseColor00">
      <BalloonStyle>   
      </BalloonStyle>
        <LineStyle>
            <color>ffffff00</color>
            <width>3</width>
        </LineStyle>
        <PolyStyle>
            <color>ffffff00</color>
            <colorMode>random</colorMode>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <Folder id="layer 0">
        <name>Test_1</name>
        <open>1</open>
        <Placemark>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM2</SimpleData>
                    <SimpleData name="cname">FM2</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.889999,-32.17281600000001,0 
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM3</SimpleData>
                    <SimpleData name="cname">FM3</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.90104,-32.15662800000001,0
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>
</Document>
</kml>
输出为: {'name':'ID'} {'name':'cname'}

我怎样才能得到dict的值,从而得到'FM2'和'FM3'


我花了几个小时试图解决这个问题。任何帮助都将不胜感激。

出于某种原因,我在您的
kml_文件的xml有效性方面遇到了问题,所以我这样做:

import lxml.html
tree  = lxml.html.fromstring(kml_file)
results = tree.xpath("//*[@name = 'ID']")

for i in results:
    if i.text:
        print(i.text)
我不确定这是否是您想要的,但输出是:

FM2
FM3

出于某种原因,我在
kml_文件的xml有效性方面遇到了问题,所以我这样做:

import lxml.html
tree  = lxml.html.fromstring(kml_file)
results = tree.xpath("//*[@name = 'ID']")

for i in results:
    if i.text:
        print(i.text)
我不确定这是否是您想要的,但输出是:

FM2
FM3

您遇到的问题之一是,当您对y中的x执行
操作时,您正在迭代当前元素的所有子元素

所以当你这样做的时候:

文档中文件夹的
:
...
您不仅仅是迭代
文件夹
元素;您还将迭代
名称
打开
模式
样式
,以及
样式映射
(暂时排除名称空间)

通过测试
name
属性值,然后返回元素文本,您仍然可以得到所需的内容

对于根目录中的文档:
对于文档中的文件夹:
对于文件夹中的Placemark:
对于Placemark中的扩展数据:
对于ExtendedData中的SchemaData:
对于SchemaData中的SimpleData:
如果SimpleData.get(“name”)=“ID”:
打印(SimpleData.text)
但我不推荐

改为考虑使用LXML函数。

这将允许您直接针对您感兴趣的元素

对于本例,我将使用完整路径,而不是
/
。我还将使用测试来测试属性值

乍一看,您可能认为所有属性值为“ID”的
SimpleData
元素的XPath是:

/kml/Document/Folder/Placemark/ExtendedData/SchemaData/SimpleData[@name='ID']
但事实并非如此。如果您注意到有一个
xmlns=”http://www.opengis.net/kml/2.2“
在根(
kml
)元素上。这意味着该元素及其所有Decentant元素都位于默认名称空间
http://www.opengis.net/kml/2.2
(除非这些元素上另有声明)

举例来说,如果您将
打印(f“In Folder element\”{Folder.tag}\“…)
添加到
for Folder In Document
循环中,您将看到:

文件夹元素中的
{http://www.opengis.net/kml/2.2}名称“。。。
“文件夹中的元素”{http://www.opengis.net/kml/2.2}打开“。。。
“文件夹中的元素”{http://www.opengis.net/kml/2.2}模式“。。。
“文件夹中的元素”{http://www.opengis.net/kml/2.2}风格“。。。
“文件夹中的元素”{http://www.opengis.net/kml/2.2}样式图“。。。
“文件夹中的元素”{http://www.opengis.net/kml/2.2}风格“。。。
“文件夹中的元素”{http://www.opengis.net/kml/2.2}文件夹“。。。
有几种处理方法,但我更喜欢在字典中声明它们,并使用
名称空间
参数传递它们

这里有一个完整的例子

从lxml导入etree
ns={“kml”:http://www.opengis.net/kml/2.2"}
tree=etree.parse(“test.kml”)
对于tree.xpath中的简单数据(“/kml:kml/kml:Document/kml:Folder/kml:Placemark/kml:ExtendedData/kml:SchemaData/kml:SimpleData[@name='ID']”,namespace=ns):
打印(简单数据.文本)
打印输出

FM2
FM3

您遇到的问题之一是,当您对y中的x执行
操作时,您正在迭代当前元素的所有子元素

所以当你这样做的时候:

文档中文件夹的
:
...
您不仅仅是迭代
文件夹
元素;您还将迭代
名称
打开
模式
样式
,以及
样式映射
(暂时排除名称空间)

通过测试
name
属性值,然后返回元素文本,您仍然可以得到所需的内容

对于根目录中的文档:
对于文档中的文件夹:
对于文件夹中的Placemark:
对于Placemark中的扩展数据:
对于ExtendedData中的SchemaData:
对于SchemaData中的SimpleData:
如果SimpleData.get(“name”)=“ID”:
打印(SimpleData.text)
但我不推荐

改为考虑使用LXML函数。

这将允许您直接针对您感兴趣的元素

对于本例,我将使用完整路径,而不是
/
。我还将使用测试来测试属性值

乍一看,您可能认为所有属性值为“ID”的
SimpleData
元素的XPath是:

/kml/Document/Folder/Placemark/ExtendedData/SchemaData/SimpleData[@name='ID']
但事实并非如此。如果您注意到有一个
xmlns=”http://www.opengis.net/kml/2.2“
在根(
kml
)元素上。这意味着该元素及其所有Decentant元素都位于默认名称空间
http://www.opengis.net/kml/2.2
(除非这些元素上另有声明)

举例来说,如果您将
打印(f“In Folder element\”{Folder.tag}\“…)
添加到
for Folder In Document
循环中,您将看到:

文件夹元素中的
{http://www.opengis.net/kml/2.2