повторно: протестируйте () XPath в HtmlAgilityPack (получите все p тегов с соответствующим внутренним регулярным выражением)

#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