Ticket #399 (closed defect: fixed)
"." expression in Stream.select/Path.select botches end tags
| Reported by: | Kyle Alan Hale <kylealanhale@…> | Owned by: | hodgestar |
|---|---|---|---|
| Priority: | major | Milestone: | 0.6.1 |
| Component: | Expression evaluation | Version: | 0.6 |
| Keywords: | Cc: |
Description
Try this out:
from genshi.template import MarkupTemplate from genshi.core import Stream def filter(stream): for event in stream: print event yield event template = MarkupTemplate('''<rhyme xmlns:py="http://genshi.edgewall.org/"> <py:match path="*[@type]"> ${select('.') | filter} </py:match> <lines> <first type="one">fish</first> <second type="two">fish</second> <third type="red">fish</third> <fourth type="blue">fish</fourth> </lines> </rhyme> ''') stream = template.generate(filter=filter) print stream.render('xml')
As a summary, this uses a py:match to find all elements with an attribute named type, selects the whole found node, and runs it through a filter to print each event in the selected stream to stdout. When I run it, I get the following output:
('START', (QName('first'), Attrs([(QName('type'), u'one')])), (None, 7, 8))
('TEXT', u'fish', (None, 7, 26))
('END', QName('first'), (None, 7, 30))
('START', (QName('second'), Attrs([(QName('type'), u'two')])), (None, 8, 8))
('TEXT', u'fish', (None, 8, 27))
('END', QName('first'), (None, 7, 30))
('START', (QName('third'), Attrs([(QName('type'), u'red')])), (None, 9, 8))
('TEXT', u'fish', (None, 9, 26))
('END', QName('first'), (None, 7, 30))
('START', (QName('fourth'), Attrs([(QName('type'), u'blue')])), (None, 10, 8))
('TEXT', u'fish', (None, 10, 28))
('END', QName('first'), (None, 7, 30))
<rhyme>
<lines>
<first type="one">fish</first>
<second type="two">fish</first>
<third type="red">fish</first>
<fourth type="blue">fish</first>
</lines>
</rhyme>
You'll see that the output keeps the ending tag of the first child element of <lines> for the following three lines. If you remove the child content of each element, the generated markup is correct, but the printed events still show incorrect END events.
This is not caused by the filtering; if you remove the filter and keep the child content, the same invalid markup is generated. The same behavior occurs no matter how the stream is rendered (html, xhtml, whatever).
Also, the same behavior occurs when the expression is changed to the equivalent "//*".

