XPath задыхается от сущностей в Firefox / GreaseMonkey - PullRequest
2 голосов
/ 14 августа 2010

Я пишу довольно простой скрипт GreaseMonkey, который находит текст в определенном элементе, а затем использует этот текст для дальнейших действий. Соответствующие биты кода следующие:

В HTML есть span с классом someclass, который содержит небольшую строку текста:

<span class="someclass">some text</span>

Затем в JavaScript я пытаюсь найти этот класс и вытянуть его содержимое («некоторый текст») в переменную, используя стандартный XPath jazz:

document.evaluate("//span[@class='someclass']/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

Вот проблема: когда я запускаю это на страницах, где «некоторый текст» является базовой строкой с базовыми символами, все работает нормально, но когда я запускаю его на страницах, где «какой-то текст» содержит сущности, происходит сбой. Например, все в порядке, и XPath возвращает нужный мне текст:

<span class="someclass">some text</span>
<span class="someclass">some other text</span>
<span class="someclass">sometext</span>
<span class="someclass">some text 12345</span>

Однако, это дает мне ошибку:

<span class="someclass">some text&#39;s text</span>

Возвращенная ошибка:

Error: The expression is not a legal expression.
Source File: file:///blahblahblah.user.js
Line: (JS line i gave above)

Я нашел несколько результатов здесь и в Google, где говорилось о том, что у XPath есть проблемы с сущностями, но все они делали что-то вроде [text() = 'blah &racquo; blah'] - другими словами, их сущности находятся в самом запросе XPath. Мои нет, они в тексте, который я пытаюсь вернуть из запроса XPath.

Это та же проблема? Есть ли простой способ обойти это?

Спасибо!

1 Ответ

1 голос
/ 14 августа 2010

Проблема в в том, что строковый литерал в выражении XPath должен быть заключен в кавычки или апострофы и не должен содержать окружающий символ.

Литеральная строка, содержащая и кавычки, и апострофы, должна быть преобразована (в вашем случае вашей программой Javascript) в строку, которая не содержит символы обоих типов.

Самый простой способ сделать это - это заменить каждый экземпляр одного из этих типов символов его символьной сущностью - скажем, заменить каждый ' на &#39; и использовать ' в качестве окружающий символ для буквальной строки.

Второй способ состоит в замене

some text&#39;s text

с выражением XPath:

concat('some text', "'", ' text')

Предупреждение : Не рекомендуется использовать ненадежные данные для создания выражения XPath - это может привести к XPath-инъекции . Чтобы избежать внедрения XPath, если ваш язык программирования и библиотеки функций позволяют это, всегда компилируйте ваше выражение XPath и запускайте его с передачей данных в качестве параметра (ов).

...