#xpath #greasemonkey
#xpath #greasemonkey
Вопрос:
Я пишу скрипт Greasemonkey, поэтому не могу изменить исходный XHTML.
Учитывая следующий фрагмент XHTML:
<td>
<span class="entry">Gender, Age:</span> Female, 42<br>
<span class="entry">Country, Town:</span> United Kingdom, London
<span class="small09"></span>
</td>
возможно ли написать выражение, которое можно вычислить с помощью document.evaluate, что позволит мне выбрать все записи, возраст которых превышает, скажем, 40? Я хочу что-то вроде следующего:
var matches = document.evaluate("//table[tbody/tr[2]/td[1][number(SOMEHOW
MATCH THE AGE PART) > 40]]",
document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
Спасибо
Комментарии:
1. Хороший вопрос, 1. Смотрите мой ответ для полного и очень короткого однострочного решения XPath-expression.
Ответ №1:
Использовать:
//table[tbody/tr[2]/td[1]
[number(
substring-after(normalize-space(span[1]/following-sibling::text()[1]),
',')
)
>
40
]
]
Комментарии:
1. 1 Правильный ответ XPath. Было бы сложно сделать что-то более общее в XPath 1.0
2. Вы уверены, что это работает в Firefox (Greasemonkey)? Я получаю:
Exception... "The expression is not a legal expression." code: "51" nsresult: "0x805b0033 (NS_ERROR_DOM_INVALID_EXPRESSION_ERR)"
.3. @Brock-Adams: Хорошая уловка — спасибо. Я исправил эту проблему (отсутствовало одно окончание
]
.4. Не получил предупреждение о вашем комментарии; Я предполагаю, что «Brock-Adams» не соответствует «Brock Adams». В любом случае, решение теперь работает и научило меня еще нескольким XPath. 1.
5. @Brock Adams: Рад, что мой ответ был полезен.
Ответ №2:
Вы не можете использовать условные обозначения для текстового содержимого, но вы можете фильтровать результаты с помощью JavaScript.
Должно сработать что-то вроде этого:
var targetCells = document.evaluate (
"//table/tbody/tr[2]/td[1]",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null
);
for (var J = targetCells.snapshotLength - 1; J >= 0; --J)
{
var thisCell = targetCells.snapshotItem (J);
//--- Get the age. Key off (fe)male, {age in decimal years}<br> in the text of the table cell
var ageTxt = thisCell.textContent.match (/male[, ] (d )/i);
if (ageTxt amp;amp; ageTxt.length > 1)
{
var age = parseInt (ageTxt[1]);
if (age > 40)
{
//-----------------------
//--- DO YOUR STUFF HERE.
//-----------------------
}
}
}
Ответ №3:
Если вы задаете возраст в качестве атрибута, вы можете получить доступ к этому значению.
Что-то вроде
<Person Gender="F" Age="42" />
Комментарии:
1. Я пишу скрипт greasemonkey и не могу изменить исходный HTML.