Artem Dumanov
Artem Dumanov

Reputation: 423

XPath to select string value of element but with <br/> replaced with newline?

Is it possible to call xpath normalize-space() on html with displaying <br>, <br/> as new line? XPath version is 1.0

We parse articles from websites. Example of real HTML code:

<div id="someid">
    <img src="https://habrastorage.org/webt/ej/ye/hp/ejyehp08ercmqzlhzh3um6mtukm.jpeg"><br>
    <br>
    Организовать удаленный доступ для сотрудников — задача прикладная. Решений на рынке немало, при этом, и подводных камней достаточно. Под катом рассказ о нашем «чемодане», который раскладывается быстро и удобно за 30 минут. Просьба не воспринимать это как рекламный BS, поскольку внутри реальная инструкция по применению.<a name="habracut"></a><br>
    <br>
    <a href="https://www.parallels.com/ru/products/ras/remote-application-server/">Parallels Remote Application Server</a> (RAS) — это комплексное средство для доставки виртуальных приложений и рабочих столов, позволяющее работать с приложениями и данными с любого устройства, в том числе мобильного. Мы понимаем, что такие решения хочется сначала протестировать в конкретных условиях, прежде чем принимать решение о покупке.     <br>
    <br>
</div>

Problem not in extracting text from site. Problem is that normalize-space is remove all tags include <br>. As a result we have one long text line. I need text line with breaks.

Expected result:

Организовать удаленный доступ для сотрудников — задача прикладная. Решений на рынке немало, при этом, и подводных камней достаточно. Под катом рассказ о нашем «чемодане», который раскладывается быстро и удобно за 30 минут. Просьба не воспринимать это как рекламный BS, поскольку внутри реальная инструкция по применению.

Parallels Remote Application Server(RAS) — это комплексное средство для доставки виртуальных приложений и рабочих столов, позволяющее работать с приложениями и данными с любого устройства, в том числе мобильного. Мы понимаем, что такие решения хочется сначала протестировать в конкретных условиях, прежде чем принимать решение о покупке.

Upvotes: 2

Views: 939

Answers (2)

Artem Dumanov
Artem Dumanov

Reputation: 423

Unfortunately, I din't solve this issue with xpath. This solution is suitable for python (scrapy framework), but algorithm is the same for other languages too.

parsed_text = remove_tags(response.xpath(record['xpath_text']).extract_first())
text = re.sub(r'\n\s*\n', '\n\n' , parsed_text).strip()

Upvotes: 0

kjhughes
kjhughes

Reputation: 111491

This XPath 2.0 expression,

string-join(
for $n in (//div[@id="someid"]//node()[self::br or self::text()]) 
    return if (name($n)='br') 
           then codepoints-to-string(10)
           else $n, '')

will join the strings of all text node descendants of the targeted div, replacing all br elements with newlines.

Upvotes: 1

Related Questions