re:test() XPath към HtmlAgilityPack (вземете всички p тагове със съответстващ вътрешен регулярен израз)

Искам всички <p>=.+=</p> тагове. Regex работи самостоятелно, без таговете <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>

person Chuck Savage    schedule 19.05.2011    source източник


Отговори (3)


Грешката, която имате, се дължи на факта, че изразът re:test използва функция на XPATH с име test (декларирана в пространство от имена, чийто префикс е re), която е неизвестна на XSLT контекста.

Не знам откъде сте взели този израз, но не е стандартен, така че не означава нищо в контекста на Html Agility Pack :-)

За задълбочено обяснение вижте тази страхотна статия тук: Добавяне на персонализирани функции към XPath . Имайте предвид, че можете да го накарате да работи с тези техники.

Това каза, ето "чиста" реализация на Html Agility Pack / XPATH:

var pNodes = htmlDoc.DocumentNode.SelectNodes("//p[text()='=.+=']");

Той използва филтър (между [ и ]) и стандартната XPATH функция text(), което означава "вътрешен текст".

person Simon Mourier    schedule 20.05.2011
comment
Благодаря ти Саймън! Търсенето на Google не помогна. - person Chuck Savage; 20.05.2011

Очевидно HtmlAgilityPack не обработва пространства от имена (не че имах такова). Така че измислих този хак,

var pNodes = htmlDoc.DocumentNode.SelectNodes("//p")
    .Where(node => Regex.Match(node.InnerText, "^=.+=$").Success);

Ако има решение на HtmlAgilityPack, ще се радвам да го чуя!

person Chuck Savage    schedule 20.05.2011

За да повторя казаното от Саймън Мурие, функцията 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

person Jamieson Christian    schedule 01.01.2016