解析 WMS XML 响应和 return 包含 key-value 对的 object

Parse WMS XML response and return an object containing key-value pairs

离开 I am trying to implement an xpath that would take the XML response example 和 return 一个 object 包含叶层标签的 key-value 对,包括名称、标题、摘要、维度:[Dimension_time, Dimension_reference_time], 样式:[样式名称、标题和 URL] 所以对于上面的 link :

Name: 'CGSL.ETA_ICEC',
Title: 'CGSL.ETA.ICEC - Fraction de glace',
Abstract: 'Le Système régional de prévision déterministe (SRPD) procède à ...',
Dimension: {
    Dimension_time: '2022-03-09T13:00:00Z/2022-03-11T12:00:00Z/PT1H',
    Dimension_ref_time: '2022-03-08T06:00:00Z/2022-03-09T12:00:00Z/PT6H'
},
Style: [
    {
        Name: 'SEA_ICECONC-LINEAR',
        Title: 'SEA_ICECONC-LINEAR',
        LegendWidth: 82,
        LegendHeight: 155,
        LegendURL: 'https://geo.weather.gc.ca/geomet?lang=fr&version=1.3.0&service=WMS&request=GetLegendGraphic&sld_version=1.1.0&layer=CGSL.ETA_ICEC&format=image/png&STYLE=SEA_ICECONC-LINEAR'
    },
    {
        Name: 'SEA_ICECONC',
        Title: 'SEA_ICECONC',
        LegendWidth: 82,
        LegendHeight: 155,
        LegendURL: 'https://geo.weather.gc.ca/geomet?lang=fr&version=1.3.0&service=WMS&request=GetLegendGraphic&sld_version=1.1.0&layer=CGSL.ETA_ICEC&format=image/png&STYLE=SEA_ICECONC'
    }
]

我的应用程序在浏览器中运行,并且我可以访问 SaxonJS,但如果本机 DomParser 可以做到这一点,它将为我移除依赖项。

axios.get('https://geo.weather.gc.ca/geomet/?service=WMS&version=1.3.0&request=GetCapabilities&LANG=en&LAYER=CGSL.ETA_ICEC')
.then((response) => {
const xslt =`XSLT`
const jsonResult = SaxonJS.XPath.evaluate(`
transform(
map { 
'source-node' : parse-xml($xml), 
'stylesheet-text' : $xslt, 
'delivery-format' : 'raw' 
}
)?output`,
[],
{ 'params': { 'xml': response.data, 'xslt': xslt }})
console.log(tempObject);

编辑:谢谢 Martin Honnen 先生

先生Honnen 提供了我一直在寻找的确切解决方案,我认为多亏了他,我更好地理解了 SaxonJS 的工作原理。像他这样的人是编程界的 backbone,我希望有一天我能像他一样帮助别人。

使用 XPath,Layer 不包含另一个 Layer 将被 Layer[not(.//Layer)] 选择(暂时忽略命名空间)。

使用 Saxon-JS 和 XPath 3.1,要在 JavaScript 端有 JavaScript 个对象和数组,您可以使用 XPath 3.1 映射 (https://www.w3.org/TR/xpath-31/#id-maps) and arrays (https://www.w3.org/TR/xpath-31/#id-arrays):

const result = SaxonJS.XPath.evaluate(`doc($url)//Layer[not(.//Layer)]!map {
  'Name' : string(Name),
  'Title' : string(Title),
  'Abstract' : string(Abstract),
  'Dimension' : map {
    'Dimension_time' : string(Dimension[@name = 'time']),
    'Dimension_ref_time' : string(Dimension[@name = 'reference_time'])
  },
  'Style' : array { Style !
    map {
      'Name' : string(Name),
      'Title' : string(Title),
      'LegendWith' : string(LegendURL/@width),
      'LegendHeight' : string(LegendURL/@height),
      'LegendURL' : string(LegendURL/OnlineResource/@xlink:href)
    }
  }
}`, null, { xpathDefaultNamespace : 'http://www.opengis.net/wms', namespaceContext : { xlink : 'http://www.w3.org/1999/xlink' }, params : { url : 'https://geo.weather.gc.ca/geomet/?service=WMS&version=1.3.0&request=GetCapabilities&LANG=en&LAYER=CGSL.ETA_ICEC' } });

console.log(result);
      
    
  
<script src="https://www.saxonica.com/saxon-js/documentation2/SaxonJS/SaxonJS2.rt.js"></script>

依赖 XPath 3.1 映射的唯一缺点是它们是无序的,因此最终结果可能看起来像

{
  "Abstract": "The Regional Deterministic Prediction System (RDPS) carries out physics calculations to arrive at deterministic predictions of atmospheric elements from the current day out to 84 hours into the future. Atmospheric elements include temperature, precipitation, cloud cover, wind speed and direction, humidity and others. This product contains raw numerical results of these calculations. Geographical coverage includes Canada and the United States. Data is available at horizontal resolution of about 10 km up to 33 vertical levels. Predictions are performed four times a day.",
  "Dimension": {
    "Dimension_time": "2022-03-10T13:00:00Z/2022-03-12T12:00:00Z/PT1H",
    "Dimension_ref_time": "2022-03-09T06:00:00Z/2022-03-10T12:00:00Z/PT6H"
  },
  "Name": "CGSL.ETA_ICEC",
  "Title": "CGSL.ETA.ICEC - Ice cover fraction",
  "Style": [
    {
      "LegendWith": "82",
      "LegendURL": "https://geo.weather.gc.ca/geomet?version=1.3.0&service=WMS&request=GetLegendGraphic&sld_version=1.1.0&layer=CGSL.ETA_ICEC&format=image/png&STYLE=SEA_ICECONC-LINEAR",
      "LegendHeight": "155",
      "Name": "SEA_ICECONC-LINEAR",
      "Title": "SEA_ICECONC-LINEAR"
    },
    {
      "LegendWith": "82",
      "LegendURL": "https://geo.weather.gc.ca/geomet?version=1.3.0&service=WMS&request=GetLegendGraphic&sld_version=1.1.0&layer=CGSL.ETA_ICEC&format=image/png&STYLE=SEA_ICECONC",
      "LegendHeight": "155",
      "Name": "SEA_ICECONC",
      "Title": "SEA_ICECONC"
    }
  ]
}

即对象的属性顺序可能与所需结果的顺序不同。

如果您将 XML 作为字符串,作为您的 response.data,请使用 parse-xml,例如

axios.get('https://geo.weather.gc.ca/geomet/?service=WMS&version=1.3.0&request=GetCapabilities&LANG=en&LAYER=CGSL.ETA_ICEC')
.then((response) => {
        const result = SaxonJS.XPath.evaluate(`parse-xml($xml)//Layer[not(.//Layer)]!map {
      'Name' : string(Name),
      'Title' : string(Title),
      'Abstract' : string(Abstract),
      'Dimension' : map {
        'Dimension_time' : string(Dimension[@name = 'time']),
        'Dimension_ref_time' : string(Dimension[@name = 'reference_time'])
      },
      'Style' : array { Style !
        map {
          'Name' : string(Name),
          'Title' : string(Title),
          'LegendWith' : string(LegendURL/@width),
          'LegendHeight' : string(LegendURL/@height),
          'LegendURL' : string(LegendURL/OnlineResource/@xlink:href)
        }
      }
    }`, null, { xpathDefaultNamespace : 'http://www.opengis.net/wms', namespaceContext : { xlink : 'http://www.w3.org/1999/xlink' }, params : { xml: response.data } });

      })