DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12235>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12235

[PATCH] XPathTransformer

           Summary: [PATCH] XPathTransformer
           Product: Cocoon 2
           Version: Current CVS
          Platform: Other
        OS/Version: Other
            Status: NEW
          Severity: Enhancement
          Priority: Other
         Component: sitemap components
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


Hi,

Attached is a transformer which lets one 'prune' an XML source, by specifying
'include' and 'exclude' XPath expressions. Ie, nodes matched by the 'include' 
expression are let through, and those matched by 'exclude' are filtered out. My
use-case is that I have a single large XML file containing a user manual, and
I'd like to render chapters of it separately. This can be done as follows:

<map:match pattern="manual/*">
  <map:generate src="manual.xml"/>
  <map:transform type="xpath">
    <map:parameter name="include" value="/manual/s1[@title='{1}']"/>
  </map:transform>
  <map:transform src="chapter2html.xsl"/>
  <map:serialize/>
</map:match>

While this sort of filtering can be done with XSLT, it can't be done
dynamically, based on an input parameter, because XSLT template patterns must
be known at 'compile' time, not runtime, much like the sitemap's matchers. See
cocoon-users discussion:
http://marc.theaimsgroup.com/?t=103069471700001&r=1&w=2

As an example use, consider the changes.xml file, of the format:

<changes title="History of Changes">
  <devs .. />
  <release version="2.1-dev">
    <action dev=".." update="..">
    ..
    </action>
    ..
  </release>
  ..
</changes>

With the attached addition to sitemap.xmap, one could have the url:

http://localhost:8080/cocoon/documents/changes/release(2.1-dev)

lists only changes in the 2.1-dev branch, by applying the transformation:

<map:match pattern="changes/release(*)">
  <map:generate src="xdocs/changes.xml"/>
  <map:transform type="xpath">
    <map:parameter name="exclude" value="/changes/release[@version != '{1}']"/>
  </map:transform>
  ..
More generally, the pattern:

<map:match pattern="changes/*(*)">
  <map:generate src="xdocs/changes.xml"/>
   <map:transform type="xpath">
     <map:parameter name="exclude" value="//action[@{1} != '{2}']"/>
   </map:transform>
   ...

Which allows one to, for instance, list all changes made by developer 'NKB' as
follows:

http://localhost:8080/cocoon/documents/changes/dev(NKB)

or list all fixes made in the different versions:

http://localhost:8080/cocoon/documents/changes/type(fix)

Which is kinda neat :)


The transformer builds a DOM, which is unfortunate but necessary for XPath. A
more SAX-friendly approach would be to use stx (http://stx.gingerall.cz/stx/).
XPathTransformer implements Cacheable to somewhat compensate for DOM yuckiness.

Feedback welcome.


--Jeff

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to