#c# #html #xpath #html-agility-pack
#c# #HTML #xpath #html-agility-pack
Вопрос:
Мне нужны все <p>=. =</p>
теги. Регулярное выражение работает само по себе, без <p>
тегов.
Вот мой XPath: "//p[re:test(.,'^=. =$', 'i')]"
Но я получаю исключение, когда подключаю его к,
HtmlNodeCollection pNodes = htmlDoc.DocumentNode.SelectNodes("//p[re:test(.,'^=. =$', 'i')]");
Исключение составляет:
Необходим менеджер пространства имен или XsltContext. Этот запрос имеет префикс, переменную или определяемую пользователем функцию.
Редактировать: Html генерируется FCKeditor и не имеет определенного пространства имен. Нужно ли мне что-то настроить, чтобы это работало?
HTML:
<p><style type="text/css">
h2 a { color: black; }</style></p>
<p>----</p>
<h2>test <a href="http://searisen.com">link</a></h2>
<p>== Heading 2 ==</p>
<p>----</p>
<p>=== Heading [http://searisen.com SeaRisen.com] ===</p>
Ответ №1:
Очевидно, HtmlAgilityPack не обрабатывает пространства имен (не то чтобы у меня их было). Итак, я придумал этот взлом,
var pNodes = htmlDoc.DocumentNode.SelectNodes("//p")
.Where(node => Regex.Match(node.InnerText, "^=. =$").Success);
Если есть решение HtmlAgilityPack, я бы хотел его услышать!
Ответ №2:
Ошибка, с которой вы столкнулись, связана с тем, что выражение re:test
использует функцию XPATH с именем test
(объявленную в пространстве имен, префикс которого re
), которая неизвестна контексту XSLT.
Я не знаю, откуда вы взяли это выражение, но оно не стандартное, поэтому оно ничего не значит в контексте Html Agility Pack 🙂
Для подробного объяснения смотрите Эту классную статью здесь: Добавление пользовательских функций в XPath. Обратите внимание, что вы могли бы заставить это работать, используя эти методы.
Тем не менее, здесь «чистая» реализация Html Agility Pack / XPATH:
var pNodes = htmlDoc.DocumentNode.SelectNodes("//p[text()='=. =']");
Он использует фильтр (между [ и ]) и стандартную функцию XPATH text(), что означает «внутренний текст».
Комментарии:
1. Спасибо, Саймон! Поиск в Google не помог.
Ответ №3:
Повторяя то, что сказал Саймон Мурье, функция re: test() не является основной функцией XPath. Это доступно в наборе функций XPath от Calibre (http://manual.calibre-ebook.com/xpath.html#term-re-test ), но это нестандартное расширение. Я не знаю ни о каких других системах, кроме Calibre, которые могут предоставлять функцию re: test().
Подробное описание основных функций XPath и функций расширения XSLT см.https://developer.mozilla.org/en-US/docs/Web/XPath/Functions