XSLT WMS GetCapabilities到JSON

XSLT WMS GetCapabilities到JSON,json,xml,xslt,saxon,saxon-js,Json,Xml,Xslt,Saxon,Saxon Js,我正在尝试将GeoMet WMS XML response.data的GetCapabilities转换为JSON,该JSON可用于v-treeviewVuetify组件,例如 编辑:其示例XML有一个根目录,只有一个标题有14组文本 <Layer queryable="1"> <Title>MSC GeoMet — GeoMet-Weather 2.14.1</Title> <Layer queryable="1&q

我正在尝试将GeoMet WMS XML response.data的GetCapabilities转换为JSON,该JSON可用于
v-treeview
Vuetify组件,例如

编辑:其示例XML有一个根目录,只有一个标题有14组文本

<Layer queryable="1">
<Title>MSC GeoMet — GeoMet-Weather 2.14.1</Title>
   <Layer queryable="1">
   <Name>Regional Deterministic Prediction System (RDPS) [10 km]</Name>
   <Title>Regional Deterministic Prediction System (RDPS) [10 km]</Title>
      <Layer queryable="1">
      <Name>RDPS - Coupled to Gulf of St. Lawrence (RDPS-CGSL)</Name>
      <Title>RDPS - Coupled to Gulf of St. Lawrence (RDPS-CGSL)</Title>
         <Layer queryable="1" opaque="0" cascaded="0">
         <Name>CGSL.ETA_ICEC</Name>
         <Title>CGSL.ETA.ICEC - Ice cover fraction</Title>
...

MSC GeoMet-GeoMet天气2.14.1
区域确定性预测系统(RDPS)[10公里]
区域确定性预测系统(RDPS)[10公里]
RDPS-连接至圣劳伦斯湾(RDPS-CGSL)
RDPS-连接至圣劳伦斯湾(RDPS-CGSL)
CGSL.ETA_ICEC
CGSL.ETA.ICEC-冰覆盖率
...

仅处理
元素(在特定名称空间
http://www.opengis.net/wms
)和第一个
标题
名称
递归地加上子
s

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    xpath-default-namespace="http://www.opengis.net/wms"
    xmlns="http://www.w3.org/2005/xpath-functions"
    expand-text="yes"
    version="3.0">

  <xsl:strip-space elements="*"/>
  
  <xsl:mode on-no-match="shallow-skip"/>

  <xsl:output method="json" build-tree="no" indent="yes"/>
  
  <xsl:template match="/WMS_Capabilities/Capability/Layer" priority="5">
    <xsl:map>
      <xsl:apply-templates/>
    </xsl:map>
  </xsl:template>
  
  <xsl:template match="Layer/Title[1] | Layer/Name[1]">
    <xsl:map-entry key="local-name()" select="data()"/>
  </xsl:template>
  
  <xsl:template match="Layer[1]">
    <xsl:map-entry key="'children'">
      <xsl:sequence select="array { ../Layer/mf:apply-templates(.) }"/>
    </xsl:map-entry>
  </xsl:template>
  
  <xsl:template match="Layer[position() > 1]"/>
  
  <xsl:function name="mf:apply-templates" as="item()*">
    <xsl:param name="elements" as="element(*)*"/>
    <xsl:map>
      <xsl:apply-templates select="$elements/*"/>      
    </xsl:map>
  </xsl:function>
  
</xsl:stylesheet>


不清楚您的输入XML格式是什么,所以至少显示一个小但有代表性的示例。我已经添加了完整XML的链接Honnen先生,并在原始帖子的编辑中添加了一个非常小的示例。有嵌套的层标记,所有的层标记都有名称和标题,我需要所有的名称和标题,这样我就可以构建一个树视图可视化工具。如果你缩进样本并将其剪切以包含基本数据,这会有所帮助。单个图层可以有多个名称或多个标题子元素吗?在这种情况下,您希望创建什么类型的JSON?注意:我向您介绍了
SaxonJS.XPath。评估
作为直接运行XSLT代码的一种方法,但要考虑到在浏览器和Node.js中更有效的方法是使用Saxon EE或使用Node.js将基于XML的XSLT代码预编译为基于JSON的SEF格式然后使用
xslt3
命令行工具运行
SaxonJS.transform
JavaScript方法来执行SEF代码。您声称我是崇拜者,我否认了Dimitre Novatchev和Michael Kay这两个虚假神。非常感谢你,先生。您的解决方案是完美的,因此我想我对XSLT有了更多的了解。不要做Dimitre或Michael冤枉的事,多亏Michael的努力(和Saxonica公司),我们有XSLT 2和3规范以及规范的Saxon实现,包括在浏览器中运行的Saxon JS和Node.JS,在Node.JS中,浏览器供应商或JavaScript公司肯定不会做出任何努力来支持与XML相关的创新。Dimitre因为某种原因成为了StackOverflow上第一个XML和XSLT的金星,他的XPath可视化工具无疑是一个多年前帮助我进入XSLT和XPath世界的工具。
<Layer queryable="1">
<Title>MSC GeoMet — GeoMet-Weather 2.14.1</Title>
   <Layer queryable="1">
   <Name>Regional Deterministic Prediction System (RDPS) [10 km]</Name>
   <Title>Regional Deterministic Prediction System (RDPS) [10 km]</Title>
      <Layer queryable="1">
      <Name>RDPS - Coupled to Gulf of St. Lawrence (RDPS-CGSL)</Name>
      <Title>RDPS - Coupled to Gulf of St. Lawrence (RDPS-CGSL)</Title>
         <Layer queryable="1" opaque="0" cascaded="0">
         <Name>CGSL.ETA_ICEC</Name>
         <Title>CGSL.ETA.ICEC - Ice cover fraction</Title>
...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    xpath-default-namespace="http://www.opengis.net/wms"
    xmlns="http://www.w3.org/2005/xpath-functions"
    expand-text="yes"
    version="3.0">

  <xsl:strip-space elements="*"/>
  
  <xsl:mode on-no-match="shallow-skip"/>

  <xsl:output method="json" build-tree="no" indent="yes"/>
  
  <xsl:template match="/WMS_Capabilities/Capability/Layer" priority="5">
    <xsl:map>
      <xsl:apply-templates/>
    </xsl:map>
  </xsl:template>
  
  <xsl:template match="Layer/Title[1] | Layer/Name[1]">
    <xsl:map-entry key="local-name()" select="data()"/>
  </xsl:template>
  
  <xsl:template match="Layer[1]">
    <xsl:map-entry key="'children'">
      <xsl:sequence select="array { ../Layer/mf:apply-templates(.) }"/>
    </xsl:map-entry>
  </xsl:template>
  
  <xsl:template match="Layer[position() > 1]"/>
  
  <xsl:function name="mf:apply-templates" as="item()*">
    <xsl:param name="elements" as="element(*)*"/>
    <xsl:map>
      <xsl:apply-templates select="$elements/*"/>      
    </xsl:map>
  </xsl:function>
  
</xsl:stylesheet>