I'm trying to filter out text from a website using lxml and Python, however, the formatting can be very irregular. (It's a forum.)
So for example, I might have:
<a>
<c>
<d>
MARKER some text
</d>
</c>
MARKER other text 1
<b>MARKER other text 2</b>
M<b>ARKE</b>R <e>other</e> text 3
</a>
I would like my xpath to return me:
MARKER other text 1
<b>MARKER other text 2</b>
M<b>ARKE</b>R <e>other</e> text 3
So in other words, I want to be able to parse nested text, but also return the text with markup.
What I currently have is:
filter = "//text()[not(parent::d[parent::c]) and contains(., 'MARKER')]"
filtered = root.xpath(self.vote_xpath)
for i in filtered:
print(i)
where root is an elementtree parsed from a string, which returns me:
MARKER other text 1
MARKER other text 2
This fails in returning me the last text with the MARKER, and fails in keeping the formatting that I want.
How should I proceed from here?
EDIT: OK, I've been fiddling a bit with the xpath.
//node()[not(parent::d[parent::c]) and contains(., 'MARKER')]
run on:
<a>
<c>
<d>
some text
</d>
</c>
other text 1
<b>other text 2</b>
M<b>ARKE</b>R <e>other</e> text 3
</a>
successfully registers the MARKER broken up by the <b> tags, since the node() passes the node entire to the contains filter. However, it returns as a match the parent node entire, in this case it simply returns the entire <a> node with all its contents.
How should I proceed so that the xpath returns only the matched portion?