如何在 Javascript XPath 中为 KML 文件生成命名空间

How can I generate a namespace for a KML file in Javascript XPath

提问人:Matt Kelly 提问时间:9/20/2021 更新时间:9/20/2021 访问量:154

问:

我想先说,我知道有很多类似的问题(在堆栈和其他网站上)与这个问题有关,但是我花了几个小时搜索互联网的每个角落和缝隙,但仍然干涸。

作为参考,我检查了以下网站,这些网站提供了一些指导,但总体上让我比以前更困惑:
https://humanwhocodes.com/blog/2009/03/24/xpath-in-javascript-part-2/
Javascript Xpath 和默认命名空间
举例说明如何从 Javascript
XPath 和 Namespaces 对 KML 文档执行 xpath 查询

好了,进入正题。我正在使用 Javascript 和 XPath 尝试读取 KML 文件。我用于获取 XML 文件的内容,然后使用以下代码尝试访问其中的 XML 节点。FileReader

const xmlParser = new DOMParser();
const xml = xmlParser.parseFromString(contents,"text/xml");  // Contents variable contains the contents of the file (as read by FileReader)

// Read XML
if (xml.evaluate) {
// Most major browsers (except IE)
    var path = "/kml/Document/Folder[1]/Placemark/Point/coordinates";

    var evaluator = new XPathEvaluator();
    var resolver = evaluator.createNSResolver(xml.documentElement);

    var nodes = xml.evaluate(path, xml.documentElement, resolver, XPathResult.ANY_TYPE, null);
    var result = nodes.iterateNext();
    while (result) {
        console.log(result);
        result = nodes.iterateNext();
    } 
}

我的 KML 文件开头是:

<?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2">
       <Document>
           <name>-/XDF</name>

由此我了解该属性定义了命名空间。当我从节点中删除此属性时,我的 Javascript 代码按预期工作(因为文件不再使用命名空间),这让我相信问题在于我没有定义正确的命名空间供 XPath 使用。xmlns

该变量是我从上面链接的站点之一复制的。我试图找到有关如何生成命名空间解析器的正确参考,但找不到适用于我的 KML 文件的东西。resolver

是否有人在这方面有更多经验能够为我指出正确的方向,以生成一个允许我读取 KML 文件的命名空间对象?

JavaScript XML XPath 命名空间 KML

评论

1赞 dandavis 9/20/2021
developer.mozilla.org/en-US/docs/Web/XPath/......

答:

1赞 Matt Kelly 9/20/2021 #1

感谢@dandavis的提示。

我需要创建一个单独的函数来返回固定的命名空间:

function resolver() {
    return 'http://www.opengis.net/kml/2.2';
}

并引用我的 XPath 路径,并带有每个节点的前缀。myns:

var path = "//myns:Document/myns:Folder[1]/myns:Placemark/myns:Point/myns:coordinates";

以下是修改后的例程(引用了上面的功能),以防它对其他人有所帮助:resolver

const xmlParser = new DOMParser();
const xml = xmlParser.parseFromString(contents,"text/xml");

// Read XML
if (xml.evaluate) {
    // Most major browsers (except IE)
    var path = "//myns:Document/myns:Folder[1]/myns:Placemark/myns:Point/myns:coordinates";

    var nodes = xml.evaluate(path, xml.documentElement, resolver, XPathResult.ANY_TYPE, null);
    var result = nodes.iterateNext();
    while (result) {
        console.log(result);
        result = nodes.iterateNext();
    } 
}
0赞 Martin Honnen 9/20/2021 #2

使用 Saxon-JS 2 (https://www.saxonica.com/saxon-js/documentation/index.html#!api/xpathEvaluate) 支持的 XPath 2 及更高版本,可以通过为 XPath 评估声明默认命名空间来保持元素的 XPath 路径紧凑且无前缀

var path = '//Document/Folder[1]/Placemark/Point/coordinates';

var result = SaxonJS.XPath.evaluate(path, xml, { xpathDefaultNamespace : 'http://www.opengis.net/kml/2.2' });

console.log(result);