2012-08-29 57 views
4

我是一个noover到stackoverflow和xslt所以我希望我不听起来不聪明!使用XSLT版本1.0从JSON文件中提取信息

因此,我正在与SDI合作为一家GIS公司工作,我有一项任务需要我将位于一个空间参考系(SRS)坐标平面上的点(例如EPSG:4035)转换为世界SRS,又名EPSG:4326。这对我来说确实不是问题,因为我拥有一个在线服务的可访问性,只会给我想要的。但是,它输出的格式是JSON或HTML格式。我已经浏览了一段时间以找到一种方法来从JSON文件中提取信息,但是我所看到的大多数技术都使用xslt:stylesheet 2.0版,并且我必须使用1.0版。我想过的一种方法是使用文档($ urlWithJsonFormat)xslt函数,但是它只接受xml文件。

这里是JSON格式的文件,我会要求在转换后恢复的例子:

{ 
    "geometries" : 
    [{ 
     "xmin" : -4, 
     "ymin" : -60, 
     "xmax" : 25, 
     "ymax" : -41 
    } 
    ] 
}

所有我只是想是XMIN,YMIN,XMAX和YMAX值,这就是全部!它似乎很简单,但对我来说没有任何作用...

+1

可以升级到XSLT 2.0?它会让事情变得更容易。 –

+1

根据您的XSLT处理器,您可以通过样式表参数传递整个jason字符串。你的处理器是什么?它是服务器端还是客户端? –

+0

应该是一个.NET处理器,切换到XSLT 2.0是不可能的。 – user1634609

回答

1

这里的两个主要选择似乎是(1)在XSLT 1.0中编写(或使用)JSON解析器,或者(2)使用除XSLT之外的其他语言。由于XSLT 1引擎通常不能直接处理JSON,我建议使用其他语言转换为XML。

https://github.com/WelcomWeb/JXS也可以帮助你,如果这是Web浏览器中的XSLT。

3

您可以使用external entity将JSON数据包含为随后转换的XML文件的一部分。

例如,假设JSON保存为一个名为“geometries.json”文件例如,你可以创建这样一个XML文件:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE wrapper [ 
<!ENTITY otherFile SYSTEM "geometries.json"> 
]> 
<wrapper>&otherFile;</wrapper> 

然后用下面的XSLT 1.0样式改造它:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="wrapper"> 
    <geometries> 
     <xsl:call-template name="parse-json-member-value"> 
      <xsl:with-param name="member" select="'xmin'"/> 
     </xsl:call-template> 
     <xsl:call-template name="parse-json-member-value"> 
      <xsl:with-param name="member" select="'ymin'"/> 
     </xsl:call-template> 
     <xsl:call-template name="parse-json-member-value"> 
      <xsl:with-param name="member" select="'xmax'"/> 
     </xsl:call-template> 
     <xsl:call-template name="parse-json-member-value"> 
      <xsl:with-param name="member" select="'ymax'"/> 
     </xsl:call-template> 
    </geometries> 
</xsl:template> 

    <xsl:template name="parse-json-member-value"> 
     <xsl:param name="member"/> 
     <xsl:element name="{$member}"> 
      <xsl:value-of select="normalize-space(
            translate(
             substring-before(
              substring-after(
               substring-after(., 
                concat('&quot;', 
                  $member, 
                  '&quot;')) 
               , ':') 
              ,'&#10;') 
            , ',', '') 
           )"/> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

生成以下的输出:

<geometries> 
    <xmin>-4</xmin> 
    <ymin>-60</ymin> 
    <xmax>25</xmax> 
    <ymax>-41</ymax> 
</geometries> 
+0

很好的答案。你可以更进一步,甚至不需要构造包装文档。文本输入可以使用document()函数直接从jason文件中获取,并使jason文档通过参数传入。 –

+1

@ SeanB.Durkin:你确定'document()'可以访问XSLT 1.0中的非XML文档吗? http://www.w3.org/TR/xslt#function-document“文档功能允许访问主源文档以外的XML文档。” – LarsH

+0

@Mads +1,很好的回答。如果他有机会将json下载并保存到一个文件中,以便外部实体能够工作,那么他也可以将它保存到具有XML包装器的文件中;在这种情况下,即使是不处理DTD的XML解析器(因为并非所有符合要求的XML解析器都需要这样做,对吗?)将能够处理包装的JSON。 – LarsH