使用 Javascript DOM 解析器从 WMS GetCapabilities 请求的 XML response.data 中提取图层列表

Using a Javascript DOM Parser extract the list of Layers from the XML response.data of an WMS GetCapabilities request

我正在尝试提取 WMS 服务器可用层的名称列表。我已经为 GeoMet WMS 这样做了,方法是发送一个 GetCapabilities,其中 returns 一个“application/xml”对象,然后我使用 DOM 解析器解析该对象。我的问题是 Layer 标签嵌套在两个级别上。基本上顶层包含多个子层。我将如何只提取子层或父层列表。我设法通过意识到子节点具有父节点没有的属性来解决这个问题,但必须有更好的方法。

编辑:我有兴趣获取可添加到交互式地图的完整图层列表。基本上所有没有 Layer children 的 Layer 标签。

axios.get('https://geo.weather.gc.ca/geomet?lang=en&service=WMS&version=1.3.0&request=GetCapabilities').then((response) => {
        // console.log(response.headers)
        const parser = new DOMParser()
        const dom = parser.parseFromString(response.data, 'application/xml')
        let layerGroups = dom.querySelectorAll('[cascaded="0"]')
        let layerNames = []
        layerGroups.forEach(function (domel) { layerNames.push(domel.getElementsByTagName('Name')[0].innerHTML) })
        console.log(layerNames.length)
        this.mylayerlist = layerNames
      })

有几种方法可以处理这个问题,尤其是命名空间。这是其中之一。在你的 dom 声明之后试试这个:

xpath = '//*[local-name()="Layer"][@cascaded="0"][not(.//*[local-name()="Layer"])]/*[local-name()="Name"]';
var targets = dom.evaluate(xpath, dom, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
let nodes = Array.from({ length: targets.snapshotLength }, (_, index) => 
console.log(targets.snapshotItem(index).innerHTML));

输出是 3,519 个(在本例中)名称:

CGSL.ETA_ICEC
CGSL.ETA_ICEPRS
CGSL.ETA_ICESTG
CGSL.ETA_ICET
CGSL.ETA_ICETK

这里的关键部分是 xpath 表达式。它选择具有 cascaded 属性且值为 0 且没有 Layer 子节点的所有 Layer 节点。在这种特殊情况下,具有 cascaded 属性的 Layer 节点中的 none(请注意,所有这些属性都具有 0 属性值)具有 Layer children,因此您可以省去两个谓词之一([@cascaded="0"][not(./*[local-name()="Layer"])] 并获得相同的输出,尽管其他文件可能不是这种情况)。