Извлечь элемент <svg> с помощью document.evaluate()?

Я пытаюсь использовать document.evaluate() извлечь определенные дочерние элементы из <svg> элемент. Но у меня есть проблемы, просто извлекая <svg> сам. Я могу извлечь все до <svg>, но не дальше. Например, это хорошо работает:

document.evaluate('//*[@id="chart"]/div/div[1]/div', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue)

Это дает мне (сокращенно):

<div style="position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;" aria-label="Et diagram.">
    <svg width="600" height="400" aria-label="Et diagram." style="overflow: hidden;"></svg>
    <div aria-label="En repræsentation i tabelformat af dataene i diagrammet." style="position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden;"></div>
</div>

и тогда я бы предположил простое

//*[@id="chart"]/div/div[1]/div/svg

дал бы мне <svg> - но ничего не работает. Перепробовал все типы ответов:

for (var type=XPathResult.ANY_TYPE; type<XPathResult.FIRST_ORDERED_NODE_TYPE+1; type ++) {
   console.dir(
      document.evaluate('//*[@id="chart"]/div/div[1]/div/svg', document, null, type, null)
   );   
}    

Я получаю либо invalidIteratorState, ноль singleNodeValue или snapshotLength из 0.

демо -> http://jsfiddle.net/hw79zp7j/

Есть ли ограничения evaluate() Я не слышал, или я просто делаю это совершенно неправильно?

Для ясности, моя конечная цель состоит в том, чтобы иметь возможность извлечь, например, визуализацию Google xAxis<text> элементы в одной строке кода. Как сейчас (см. Демонстрацию), я должен перебрать <svg> используя несколько querySelectorAll / getElementsByTagName и т. д., который не очень читабелен, удобен в обслуживании или элегантен. Было бы неплохо просто взять xpath из инструментов разработчика Google и повторно использовать его в одной строке.

1 ответ

Решение

SVG элементы находятся в пространстве имен http://www.w3.org/2000/svg и для выбора элементов в пространстве имен с помощью XPath вам необходимо привязать префикс к URI пространства имен и использовать этот префикс в вашем пути для определения имен элементов, например svg:svg, Так что используйте резольвер в качестве третьего аргумента evaluate который отображает префикс, который вы можете выбрать (например, svg) к указанному выше URI пространства имен.

document.evaluate('//*[@id="chart"]/div/div[1]/div/svg:svg', document, 
                                function(prefix) { 
                                    if (prefix === 'svg') 
                                    { 
                                        return 'http://www.w3.org/2000/svg';
                                    }
                                    else
                                    {
                                        return null;
                                    }
                                }, type, null)
Другие вопросы по тегам