cross-posting http://genshi.edgewall.org/ticket/521

 While customizing my Trac installation, I ran across a particularly sticky 
problem: it does not seem possible to use the contains() xpath function in 
genshi in a way that allows conditionally selecting an element based on its 
contents. 

The particular example are labels in the change history for Trac. These are 
inside strong tags, but have no tag metadata to use for the xpath selector, 
so matching on the contents of the strong tag is the only way to alter the 
ones I want. 

The non-working code that I believe should work: 

{{{#!html 

 <!-- 

 Rewrite labels in the change history. This is busted but *should* work The 
error I get is: 

 File 
"/usr/lib/python2.6/site-packages/Genshi-0.6-py2.6.egg/genshi/path.py", 

 line 932, in as_float return float(as_scalar(value)) 
ValueError?<http://genshi.edgewall.org/wiki/ValueError>: 
invalid literal for float(): . 

  --> 

 <strong py:match="ul[@class='changes']/li/strong[contains(.,'Reporter')]" 

 py:attrs="select('@*')"> 

 Champion: 

 </strong> 

 }}} 

Also tried *text()* instead of *.* in contains(), that also errors out. 

Here is the code I finally got to work, after literally hours of screwing 
around and research: 

{{{#!html 

 <!-- 

 Rewrite labels in the change history. 

  --> 

 <strong py:match="ul[@class='changes']/li/strong" 

 py:attrs="select('@*')"> 

 <py:with vars="text=select('text()').render();"> 

 <py:choose test="text"> 

 <py:when test="'Owner'">Liaison</py:when> <py:when 
test="'Reporter'">Champion</py:when> <py:when 
test="'Milestone'">Target</py:when> <py:otherwise>$text</py:otherwise> 

 </py:choose> 

 </py:with> 

 </strong> 

 }}} 

If I hadn't eventually realized that select() is represented as a stream 
instead of a string, I never would have gotten this working, either. 
Thankfully the documentation at 
http://genshi.edgewall.org/wiki/Documentation/0.5.x/streams.html#serializationprovided
 me with the render() method so I could finally compare strings in 
py:choose. 

I'd like to strongly advocate that contains() be fixed to work properly, as 
it shouldn't be necessary to jump through all these hoops in order to match 
on an element's contents. 

-- 
You received this message because you are subscribed to the Google Groups "Trac 
Development" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/trac-dev/-/-1aLw69pIDkJ.
To post to this group, send email to trac-dev@googlegroups.com.
To unsubscribe from this group, send email to 
trac-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/trac-dev?hl=en.

Reply via email to