在 HTML5 中注入自定义元素,然后使用 XPath 检索其值返回空白

Injecting a custom element in HTML5 then retrieving its value using XPath comes back blank

我正在注入从 Web 服务生成的 XML 字符串,然后尝试使用 XPath 通过以下代码查询属性值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>tox-js</title>
</head>
<body>
    <script>
    //
    // -----------------------------------------------
    // tox element
    class Tox extends HTMLElement
        {
        constructor(url)
            {
            super();
            fetch(url)
                .then((response)=>
                    {
                    console.log("status: "+response.status);
                    return response.text();
                    })
                .then((text)=>
                    {
                    console.log("text: "+text);
                    try
                        {
                        var dp = new DOMParser();
                        var xmlDOM = dp.parseFromString(text, "text/xml");
                        this.appendChild(xmlDOM.documentElement);
                        return true;
                        }
                    catch(err)
                        {
                        console.log("err: "+err.message);
                        return false;
                        }
                    })
                .then((ok)=>
                    {
                    if (ok)
                        {
                        try
                            {
                            var xpe = new XPathEvaluator();
                            var txt = xpe.evaluate("//tox-js/example/@timestamp",document,null,XPathResult.STRING_TYPE,null);
                            console.log("//tox-js/example/@timestamp: "+txt.stringValue);
                            txt = xpe.evaluate("//tox-js/example/@feedback",document,null,XPathResult.STRING_TYPE,null);
                            console.log("//tox-js/example/@feedback: "+txt.stringValue);
                            }
                        catch(err)
                            {
                            console.log("err: "+err.message);
                            }
                        }
                    else
                        console.log("not ok");
                    }
                    );
            }
        }
    //
    // -----------------------------------------------
    // register our element with the DOM
    customElements.define('tox-js',Tox);
    //
    // -----------------------------------------------
    // create an instance and add it to the body
    document.body.appendChild(new Tox('http://localhost:8080/tox/example.test.formatted?in_mask=YYYYMMDD'));
    // -----------------------------------------------
    //
    </script>
</body>
</html>

结果注入了自定义元素。

<html lang="en">
    <head>...</head>
    <body>
        <script>...</script>
        <tox-js>
            <example timestamp="20180103142036" feedback="ok">20190103</example>
        </tox-js>
    </body>
<html>

控制台日志确认 return 状态和 XML,但 XPath 的结果为空。

[Log] status: 200 (toxElement3.html, line 20)
[Log] text: <example timestamp="20190103142036" feedback="ok">20190103</example> (toxElement3.html, line 25)
[Log] //tox-js/example/@timestamp:  (toxElement3.html, line 47)
[Log] //tox-js/example/@feedback:  (toxElement3.html, line 49)

我哪里做错了?这应该不是时间问题,因为我正在使用 .then 等待上一步。

似乎与命名空间有关。 以下 XPath 对我有用:

//tox-js/*[local-name()='example']/@timestamp

检查这个答案: XPath Doesn't Work in Dynamic HTML-Document

你也可以使用document.createElement() or insertAdjacentHTML() to create element from text as described here: Creating a new DOM element from an HTML string using built-in DOM methods or Prototype

在这种情况下,您的 XPath 将按预期工作。

<html lang="en">
    <head></head>
    <body>
        <script>
            window.addEventListener('load', () => {
                var text = `<example timestamp="20180103142036" feedback="ok">20190103</example>`;
                var el = document.getElementsByTagName('tox-js')[0];
                el.insertAdjacentHTML('afterbegin', text);

                var xpe = new XPathEvaluator();
                var txt = xpe.evaluate("//tox-js/example/@timestamp",document,null,XPathResult.STRING_TYPE,null);
                console.log(`//tox-js/example/@timestamp: ${txt.stringValue}`);
            });
        </script>
        <tox-js>
        </tox-js>
    </body>
<html>

P.S。我无法解释为什么在使用 DOMParser 时会出现问题。也许 documentDOMParser 有不同的命名空间。因此,如果有人有更多详细信息,请随时扩展答案。

从提供的例子...

var dp = new DOMParser();
var xmlDOM = dp.parseFromString(text, "text/xml");
this.appendChild(xmlDOM.documentElement);

...变成...

this.insertAdjacentHTML('afterbegin', text);