Project

General

Profile

Actions

Feature #5013

closed

Support every XPath functions in all contexts

Added by Reynaud Sylvain over 10 years ago. Updated over 10 years ago.

Status:
Resolved
Priority:
High
Assigned To:
Category:
Engine
Target version:
Start date:
09/12/2013
Due date:
% Done:

100%

Estimated time:

Description

Refactoring steps:
1) develop java class to invoke <processor> for all SELECTED and DESCENDANT_OF_SELECT events.
2) support new syntax:

  • develop XSL to translate new syntax to current syntax (for pre-processing).
  • develop XSL to translate current syntax to new syntax (for lavoisier-update-config.sh).

3) support Lavoisier XPath functions in PiXTL short notation (modify XSL to translate PiXTL short notation to new syntax).
4) support new syntax hidden parameters

  • modify XSL to generate hidden parameters.
  • instanciate plug-in from new syntax.

5) refactoring: move AbstractSAXPathProcessor to engine:

  • modify adaptor interfaces.
  • modify engine.
Language modifications:
  • replace parameter "nodes" with attribute @match.
  • replace parameter "namespaces" with xmlns:ns.
  • replace parameters "variables" and "xml_variables" with <variable xml="true|FALSE"/>.
  • support all XPath functions in both context, except function matched().

Pre-processing steps:
1) add parameter types from processors:

  • constant: never evaluated.
  • relative path: potentially evaluated for each node.
  • expression: evaluated for each selected node (text() is converted to 'constant', and @eval is converted to $variable).

2) convert XPath to XML tree <eval>.
3) optimize:

  • move the XPath functions that have no descendant::RelativeLocationPath (nor path relative to function matched()) to variables.
  • add attribute @onEvents to <parameter>.
  • convert XML tree <eval> to XPath @eval.

Example with actual notation:

<processor type="ReplaceProcessor">
    <parameter name="namespaces">
        <entry key="e">http://software.in2p3.fr/lavoisier/entries.xsd</entry>
    </parameter>
    <parameter name="variables">
        <entry key="prefix" eval="path('prefix')"/>
    </parameter>
    <parameter name="xml_variables">
        <entry key="xml" eval="request()"/>
    </parameter>
    <parameter name="nodes">/e:entries/e:entry[@key &lt; $xml/@value]</parameter>
    <parameter name="node_prefix" eval="property('ns.entries')"/>
    <parameter name="node_name">concat(path('prefix'),'-suffix')</parameter>
    <parameter name="node_name_as_xpath">true</parameter>
    <parameter name="node_value">'1'</parameter>
</processor>

The same example with target notation:

<processor type="ReplaceProcessor" xmlns:e="http://software.in2p3.fr/lavoisier/entries.xsd" 
           match="/e:entries/e:entry[@key &lt; request()/@value]">
    <parameter name="node_prefix" eval="property('ns.entries')"/>
    <parameter name="node_name" eval="concat(path('prefix'),'-suffix')"/>
    <parameter name="node_value">1</parameter>
</processor>

The same example optimized by Lavoisier:

<processor type="ReplaceProcessor" xmlns:e="http://software.in2p3.fr/lavoisier/entries.xsd" 
           match="/e:entries/e:entry[@key &lt; $_match1]">
    <variable name="_match1" eval="request()/@value"/>
    <variable name="_node_name1" eval="concat(path('prefix'),'-suffix')"/>
    <parameter name="node_prefix" eval="property('ns.entries')"/>
    <parameter name="node_name">$_node_name1</parameter>
    <parameter name="node_value">'1'</parameter>
</processor>

Example XPath expression:
choose(
    $a != @id,
    view('v', arguments() | entry('k', post()/*/*[@id=$a])),
    view('v', arguments() | entry('k', post()/*/*[@id=current()/*/*[@name=property('name')]/@id]))
)

Then the following expressions must be evaluated for each selected event:
  • @id
  • current()/*/*[@name=$_4]/@id
Main benefits:
  • less verbose.
  • same XPath functions in both contexts.
  • any parameter can be evaluated as an XPath expression.
Actions #1

Updated by Reynaud Sylvain over 10 years ago

  • Subject changed from <processor> : evaluate XPath in engine instead of plug-in to Support every XPath functions in all contexts
  • Description updated (diff)
Actions #2

Updated by Reynaud Sylvain over 10 years ago

  • Target version set to 2.0
Actions #3

Updated by Reynaud Sylvain over 10 years ago

  • Category set to Engine
Actions #4

Updated by Reynaud Sylvain over 10 years ago

  • Description updated (diff)
Actions #5

Updated by Reynaud Sylvain over 10 years ago

  • Description updated (diff)
Actions #6

Updated by Reynaud Sylvain over 10 years ago

<!-- PiXTL processors -->
<processor match="/root/child" type="AppendAggregateProcessor">
    <parameter name="node_name">new</parameter><!-- constant -->
    <parameter name="node_values" eval="leaf/@id"/><!-- relative path -->
</processor>
<processor match="/root/child" type="InsertProcessor">
    <parameter name="node_name">new</parameter><!-- expression -->
    <parameter name="node_value" eval="@value"/><!-- expression -->
</processor>
<processor match="/root/child" type="InsertAsParentProcessor"/>
<processor match="/root/child" type="ReplaceProcessor">
    <parameter name="node_name">new</parameter><!-- expression -->
    <parameter name="node_value" eval="@value"/><!-- expression -->
</processor>
<processor match="/root/child" type="MergeProcessor"/>
<processor match="/root/child" type="RemoveProcessor"/>
<processor match="/root/child" type="SelectProcessor"/>
<processor match="/root/child" type="SelectIfDescendantProcessor">
    <parameter name="if_descendant_name">leaf</parameter><!-- constant -->
    <parameter name="if_descendant_predicate" eval="@id='1'"/><!-- PREDICATE ??? -->
</processor>
<processor match="/root/child" type="MoveProcessor">
    <parameter name="destination_name">leaf</parameter><!-- constant -->
    <parameter name="destination_predicate" eval="@id='1'"/><!-- PREDICATE ??? -->
</processor>
<processor match="/root/child" type="SelectGroupByProcessor">
    <parameter name="group_by" eval="leaf/@id"/><!-- relative path -->
</processor>
<processor match="/root/child/leaf/@id" type="SelectDistinctProcessor"/>

<!-- other processors -->
<processor match="/root/child" type="LogProcessor">
    <parameter name="message" eval="concat('identifier = ', @id)"/><!-- expression -->
</processor>
<processor match="//*" type="CaseProcessor"/>

<!-- PiXTL alternatives -->
<processor match="/root/child" type="InsertProcessor">
    <!-- instead of node_* (=> could be merged with InsertXmlProcessor) -->
    <parameter name="node" eval="create-element('ns:new', @value)"/>
</processor>
<processor match="/root/child/descendant-or-self::*" type="SelectProcessor | RemoveProcessor">
    <!-- instead of @depth -->
    <parameter name="recursive">false</parameter>
</processor>
<processor match="/root/child" type="SelectIfDescendantProcessor">
    <!-- instead of if_descendant_* -->
    <parameter name="if_nodes" eval="subchild/leaf[@id='1']"/>
</processor>
<processor match="/root/child" type="MoveProcessor">
    <!-- relative path with ancestor or following+descendant only -->
    <parameter name="destination" eval="leaf[@id='1']"/>
</processor>
Actions #7

Updated by Reynaud Sylvain over 10 years ago

  • Description updated (diff)
Actions #8

Updated by Reynaud Sylvain over 10 years ago

  • Status changed from New to Resolved
  • Assigned To set to Reynaud Sylvain
  • % Done changed from 0 to 100
Actions

Also available in: Atom PDF