Внедрение пользовательского элемента в HTML5 с последующим извлечением его значения с использованием XPath возвращается пустым - PullRequest
0 голосов
/ 04 января 2019

Я внедряю строку 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>

Журнал консоли подтверждает статус возврата и 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 для ожидания предыдущего шага.

1 Ответ

0 голосов
/ 04 января 2019

Кажется, это связано с пространствами имен.У меня работает следующий XPath:

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

Проверьте этот ответ: XPath не работает в динамическом HTML-документе

Также вы можете использовать document.createElement() или insertAdjacentHTML() для создания элемента из текста, как описано здесь: Создание нового элемента DOM из строки HTML с использованием встроенных методов DOM или прототипа

В этом случае ваш 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>

PS Я не могу объяснить, почему проблема возникает при использовании DOMParser.Возможно, существуют разные пространства имен для document и DOMParser.Так что, если у кого-то есть более подробная информация, не стесняйтесь расширять ответ.

Из предоставленного примера ...

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

... становится ...

this.insertAdjacentHTML('afterbegin', text);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...