使用XSLT转换XML(前身为KML)

6

你好,我正在尝试使用w3schools XSLT Tryit编辑器将KML文件(保存为XML文件)转换,但似乎无法使其工作。以下是我的XML文件片段:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
 <Document>
  <name>Bnsf RR cut</name>
  <open>1</open>
  <Style>
   <ListStyle>
    <ItemIcon>
     <href>kmzicon.png</href>
    </ItemIcon>
   </ListStyle>
  </Style>
  <Folder>
   <name>11/10/11 8:17:20 AM</name>
   <Placemark>
    <name>Track</name>
   </Placemark>
  </Folder>
  <Placemark>
   <name>Gray Mesa</name>
   <description><![CDATA[<img width="800" src="1.jpg"/>]]></description>
   <Point>
    <coordinates>-106.493097,34.446357,1692.000000</coordinates>
   </Point>
  </Placemark>
 </Document>
</kml>

我的XSLT代码如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
      <xsl:for-each select="Document/Placemark">
        <xsl:value-of select="name"/>
        <xsl:value-of select="description"/>
      </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

如果我在XML代码中删除kml标签,它就可以正常工作,但我更想尝试自动化处理,而不必从许多XML中删除代码。我已经尝试将"kml"添加到我的XSLT代码"/kml/Document/Placemark">,但这并没有起作用。谢谢!
我希望转换后的XML如下所示:
 <Document> 
  <Placemark>
   <name>Gray Mesa</name>
   <description><![CDATA[<img width="800" src="1.jpg"/>]]></description>
   <Point>
    <coordinates>-106.493097,34.446357,1692.000000</coordinates>
   </Point>
  </Placemark>
 </Document>

我认为这对我的目的很有效。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kml="http://www.opengis.net/kml/2.2">
   <xsl:template match="/">
  <xsl:for-each select="kml:kml/kml:Document/kml:Placemark">
     <name><xsl:value-of disable-output-escaping="yes" select="kml:name"/></name>
     <description><xsl:value-of disable-output-escaping="yes" select="kml:description"/></description>
  </xsl:for-each>
 </xsl:template>

每个名称和描述标签都包括如下内容:xmlns:kml="http://www.opengis.net/kml/2.2" 不过,我可以将其与Access查询拼接起来。但是,当我尝试导入Access时,出现了一个错误。它说我需要一个根文件夹,因为我只有很多名称和描述标签。是否有办法使用XSL添加一个标签呢?非常感谢。抱歉我的问题有些混乱,我一直在编辑它。

我认为问题出在命名空间声明上。目前我还没有解决这个问题的方法,但是有趣的是,如果你将循环改为“kml/Document/Placemark”,并从<kml>元素中删除命名空间声明,它就可以工作了。 - Colin D
3个回答

4

Tim C 关于命名空间的说法是正确的,但我想补充一下,XSLT 是一种声明性语言,因此通常在样式表中看到 for-each 时,可以用更适合该语言的方法进行替换。因此,我会使用以下代码。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kml="http://www.opengis.net/kml/2.2">
  <xsl:output method="text"/>

   <xsl:template match="/">
      <xsl:apply-templates select="kml:kml/kml:Document/kml:Placemark"/>
   </xsl:template>

   <xsl:template match="kml:Placemark">
         <xsl:value-of select="kml:name"/>
         <xsl:value-of select="kml:description"/>
   </xsl:template>

</xsl:stylesheet>

非常感谢。我正在尝试将转换后的XML导入Access,但无法正常工作。我收到了语法错误。新转换的XML只是一行长代码:Top of council spring<img width="800" src="38.jpg"/>.... 有没有办法在新的XML中保留<name>和<description>标签?我正在尝试使用Access中的TransformXML方法仅提取名称和描述,因为原始KML文件中有很多不需要的额外代码。谢谢。希望这样说得清楚。 - Andrew
将输出方式更改为xml,然后使用 <xsl:copy-of select="kml:name"/> <description><xsl:value-of disable-output-escaping="yes" select="kml:description"/></description> - BeWarned
你好,感谢你的帮助。我已经发布了一个可以使用的解决方案。有没有一种简单的方法让XSL添加一个根文件夹?或者只是让XSL保留根<Document>标签? - Andrew
你只需要用你想要的标签将名称和描述包围起来: <root> <xsl:value-of select="kml:name"/> <xsl:value-of select="kml:description"/> </root> 或者为kml:Document创建模板,并在那里创建根节点。 - BeWarned

2
这是因为您的XML中有一个默认命名空间。
<kml xmlns="http://www.opengis.net/kml/2.2" ...

在XPath 1.0中,您必须为想要使用的每个命名空间指定前缀。类似于 Document/Placemark 的路径只会选择没有命名空间的 Placemark 元素。
尝试使用此XSLT。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kml="http://www.opengis.net/kml/2.2">
   <xsl:template match="/">
      <xsl:for-each select="kml:kml/kml:Document/kml:Placemark">
         <xsl:value-of select="kml:name"/>
         <xsl:value-of select="kml:description"/>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

请注意,使用<xsl:template match="/">匹配文档元素,这与文档kml的根元素不是同一件事。

这是一篇关于默认命名空间的好文章:http://www.jenitennison.com/blog/node/36

请注意,您可能希望这样做,以输出描述的 CDATA。

<xsl:value-of select="kml:description" disable-output-escaping="yes"/>

0

如果你只是处理Kml中的地标,我建议使用KMLCSV转换器。(http://sourceforge.net/projects/kmlcsv/)

但它不能用于线条或多边形。

谢谢

Shane


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接