i have got some trouble, using the XPath. (Later i want to add my expression on SonarQube to rule of xpath pattern so i can create my own rules there. But SonarQube is not required yet)
I want to create a rule which throws exception if a project was analyzed and something special was written in the comments (e.g. "ERROR") of my java projects (e.g. myXPathTry.java).
I am testing all my expressions with this SSLR Toolkit. Just need to download it and execute it.
Usage is simple: add your code on the left, click "Parse Source Code" right under the box. Then add your xpath rule in the box on the bottom and finally click "Evaluate XPath". Result should be marked. You are also allowed to view the automatic created XML for your source code if you click the xml button above the right box.
My problem is: all the comments are saved in "unaccessable" TRIVIA path (as you can see in the AST). I can access all other things and check against there values and parameters, but not this TRIVIA stuff. (JavaCode, AST (Abstract Syntax Tree) and XML are added below.)
Do you know a way how i can get access to the comments?
Thanks for your Help! :)
Already tested:
neighter //*/comment() , nor //*/TOKEN/TRIVIA does have any effect.
//*/TOKEN works and has affect, but does not contain the needed information.
Java Code:
public class MyXPathTry{
public static void main(String[] args){
System.out.println("Just to have some code");
//This is a comment
/* This is a second comment */
/* This is a second comment with ERROR*/
}
}
In the AST the blue line (RWING, if image is not visable) was selectet after i clicked on any comment on the left of the toolkit. Path downwards was not opend by default. I opened RWING and the TOKEN subfolder by myself, just do show you what i mean with TRIVIA files)
Toolkit Auto-Created XML:
<compilationUnit tokenValue="public" tokenLine="1" tokenColumn="0">
<typeDeclaration tokenValue="public" tokenLine="1" tokenColumn="0">
<modifier tokenValue="public" tokenLine="1" tokenColumn="0">
<PUBLIC tokenValue="public" tokenLine="1" tokenColumn="0">
<TOKEN tokenValue="public" tokenLine="1" tokenColumn="0"/>
</PUBLIC>
</modifier>
<classDeclaration tokenValue="class" tokenLine="1" tokenColumn="7">
<CLASS tokenValue="class" tokenLine="1" tokenColumn="7">
<TOKEN tokenValue="class" tokenLine="1" tokenColumn="7"/>
</CLASS>
<IDENTIFIER tokenValue="MyXPathTry" tokenLine="1" tokenColumn="13">
<TOKEN tokenValue="MyXPathTry" tokenLine="1" tokenColumn="13"/>
</IDENTIFIER>
<classBody tokenValue="{" tokenLine="1" tokenColumn="23">
<LWING tokenValue="{" tokenLine="1" tokenColumn="23">
<TOKEN tokenValue="{" tokenLine="1" tokenColumn="23"/>
</LWING>
<classBodyDeclaration tokenValue="public" tokenLine="2" tokenColumn="4">
<modifier tokenValue="public" tokenLine="2" tokenColumn="4">
<PUBLIC tokenValue="public" tokenLine="2" tokenColumn="4">
<TOKEN tokenValue="public" tokenLine="2" tokenColumn="4"/>
</PUBLIC>
</modifier>
<modifier tokenValue="static" tokenLine="2" tokenColumn="11">
<STATIC tokenValue="static" tokenLine="2" tokenColumn="11">
<TOKEN tokenValue="static" tokenLine="2" tokenColumn="11"/>
</STATIC>
</modifier>
<memberDecl tokenValue="void" tokenLine="2" tokenColumn="18">
<VOID tokenValue="void" tokenLine="2" tokenColumn="18">
<TOKEN tokenValue="void" tokenLine="2" tokenColumn="18"/>
</VOID>
<IDENTIFIER tokenValue="main" tokenLine="2" tokenColumn="23">
<TOKEN tokenValue="main" tokenLine="2" tokenColumn="23"/>
</IDENTIFIER>
<voidMethodDeclaratorRest tokenValue="(" tokenLine="2" tokenColumn="27">
<formalParameters tokenValue="(" tokenLine="2" tokenColumn="27">
<LPAR tokenValue="(" tokenLine="2" tokenColumn="27">
<TOKEN tokenValue="(" tokenLine="2" tokenColumn="27"/>
</LPAR>
<formalParameterDecls tokenValue="String" tokenLine="2" tokenColumn="28">
<type tokenValue="String" tokenLine="2" tokenColumn="28">
<classType tokenValue="String" tokenLine="2" tokenColumn="28">
<IDENTIFIER tokenValue="String" tokenLine="2" tokenColumn="28">
<TOKEN tokenValue="String" tokenLine="2" tokenColumn="28"/>
</IDENTIFIER>
</classType>
<dim tokenValue="[" tokenLine="2" tokenColumn="34">
<LBRK tokenValue="[" tokenLine="2" tokenColumn="34">
<TOKEN tokenValue="[" tokenLine="2" tokenColumn="34"/>
</LBRK>
<RBRK tokenValue="]" tokenLine="2" tokenColumn="35">
<TOKEN tokenValue="]" tokenLine="2" tokenColumn="35"/>
</RBRK>
</dim>
</type>
<formalParametersDeclsRest tokenValue="args" tokenLine="2" tokenColumn="37">
<variableDeclaratorId tokenValue="args" tokenLine="2" tokenColumn="37">
<IDENTIFIER tokenValue="args" tokenLine="2" tokenColumn="37">
<TOKEN tokenValue="args" tokenLine="2" tokenColumn="37"/>
</IDENTIFIER>
</variableDeclaratorId>
</formalParametersDeclsRest>
</formalParameterDecls>
<RPAR tokenValue=")" tokenLine="2" tokenColumn="41">
<TOKEN tokenValue=")" tokenLine="2" tokenColumn="41"/>
</RPAR>
</formalParameters>
<methodBody tokenValue="{" tokenLine="2" tokenColumn="42">
<block tokenValue="{" tokenLine="2" tokenColumn="42">
<LWING tokenValue="{" tokenLine="2" tokenColumn="42">
<TOKEN tokenValue="{" tokenLine="2" tokenColumn="42"/>
</LWING>
<blockStatements tokenValue="System" tokenLine="3" tokenColumn="1">
<blockStatement tokenValue="System" tokenLine="3" tokenColumn="1">
<statement tokenValue="System" tokenLine="3" tokenColumn="1">
<expressionStatement tokenValue="System" tokenLine="3" tokenColumn="1">
<statementExpression tokenValue="System" tokenLine="3" tokenColumn="1">
<expression tokenValue="System" tokenLine="3" tokenColumn="1">
<primary tokenValue="System" tokenLine="3" tokenColumn="1">
<qualifiedIdentifier tokenValue="System" tokenLine="3" tokenColumn="1">
<IDENTIFIER tokenValue="System" tokenLine="3" tokenColumn="1">
<TOKEN tokenValue="System" tokenLine="3" tokenColumn="1"/>
</IDENTIFIER>
<DOT tokenValue="." tokenLine="3" tokenColumn="7">
<TOKEN tokenValue="." tokenLine="3" tokenColumn="7"/>
</DOT>
<IDENTIFIER tokenValue="out" tokenLine="3" tokenColumn="8">
<TOKEN tokenValue="out" tokenLine="3" tokenColumn="8"/>
</IDENTIFIER>
<DOT tokenValue="." tokenLine="3" tokenColumn="11">
<TOKEN tokenValue="." tokenLine="3" tokenColumn="11"/>
</DOT>
<IDENTIFIER tokenValue="println" tokenLine="3" tokenColumn="12">
<TOKEN tokenValue="println" tokenLine="3" tokenColumn="12"/>
</IDENTIFIER>
</qualifiedIdentifier>
<identifierSuffix tokenValue="(" tokenLine="3" tokenColumn="19">
<arguments tokenValue="(" tokenLine="3" tokenColumn="19">
<LPAR tokenValue="(" tokenLine="3" tokenColumn="19">
<TOKEN tokenValue="(" tokenLine="3" tokenColumn="19"/>
</LPAR>
<expression tokenValue=""Just to have some code"" tokenLine="3" tokenColumn="20">
<primary tokenValue=""Just to have some code"" tokenLine="3" tokenColumn="20">
<literal tokenValue=""Just to have some code"" tokenLine="3" tokenColumn="20">
<LITERAL tokenValue=""Just to have some code"" tokenLine="3" tokenColumn="20">
<TOKEN tokenValue=""Just to have some code"" tokenLine="3" tokenColumn="20"/>
</LITERAL>
</literal>
</primary>
</expression>
<RPAR tokenValue=")" tokenLine="3" tokenColumn="44">
<TOKEN tokenValue=")" tokenLine="3" tokenColumn="44"/>
</RPAR>
</arguments>
</identifierSuffix>
</primary>
</expression>
</statementExpression>
<SEMI tokenValue=";" tokenLine="3" tokenColumn="45">
<TOKEN tokenValue=";" tokenLine="3" tokenColumn="45"/>
</SEMI>
</expressionStatement>
</statement>
</blockStatement>
</blockStatements>
<RWING tokenValue="}" tokenLine="7" tokenColumn="4">
<TOKEN tokenValue="}" tokenLine="7" tokenColumn="4"/>
</RWING>
</block>
</methodBody>
</voidMethodDeclaratorRest>
</memberDecl>
</classBodyDeclaration>
<RWING tokenValue="}" tokenLine="8" tokenColumn="0">
<TOKEN tokenValue="}" tokenLine="8" tokenColumn="0"/>
</RWING>
</classBody>
</classDeclaration>
</typeDeclaration>
<EOF tokenValue="" tokenLine="8" tokenColumn="1"/>
</compilationUnit>
.
This is not possible. For your information the ability to write custom rules in XPath will be dropped in favor of writing them in Java.
Related
Given the XML below, I am trying to write a XPath which returns only this match:
<TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />
This is the input file:
<?xml version="1.0" encoding="utf-8"?>
<DOCUMENT>
<SECTION>
<PARAGRAPH TRACK="4">
<SENTENCE NAME="PRIMARY" COUNT="4">
<TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
<TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />
<TOKEN BEGIN="167" END="169" SENTENCE_BEGIN="158" SENTENCE_END="316" />
<TOKEN BEGIN="210" END="215" SENTENCE_BEGIN="158" SENTENCE_END="316" />
</SENTENCE>
<SENTENCE NAME="SECONDARY" COUNT="2">
<TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
<TOKEN BEGIN="143" END="145" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="B" />
</SENTENCE>
<SENTENCE NAME="SECONDARY" COUNT="1">
<TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />
</SENTENCE>
</PARAGRAPH>
</SECTION>
</DOCUMENT>
This is my xpath string:
//TOKEN [#DOUBLE] [#BEGIN <= ../../SENTENCE[#NAME='PRIMARY']/TOKEN/#END] [ (#SENTENCE_BEGIN = ../../SENTENCE[#NAME='PRIMARY']/TOKEN/#SENTENCE_BEGIN) and (#SENTENCE_END = ../../SENTENCE[#NAME='PRIMARY']/TOKEN/#SENTENCE_END) ]
I receive as output two nodes:
<TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />
and
<TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
The result above is not correct because I want to check that:
the SENTENCE_BEGIN SENTENCE_END values of TOKEN[#DOULBE=YES] and
SENTENCE[#NAME="PRIMARY"]/TOKEN are the same, and
the value of the attribute BEGIN of TOKEN[#DOULBE=YES] is less than the BEGIN of SENTENCE[#NAME="PRIMARY"]/TOKEN
The result
<TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
is not correct, as the BEGIN value (139) is greater than the corresponding BEGIN values of the tokens with the same SENTENCE_BEGIN SENTENCE_END values:
<TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
<TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />
How can I modify the code line to obtain the desired result?
Since you've tagged your question XSLT 1.0, I'd use XSLT instead of pure XPath. That way you can use xsl:key and also current().
Example...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="primary_tokens"
match="SENTENCE[#NAME='PRIMARY']/TOKEN"
use="concat(#SENTENCE_BEGIN,'|',#SENTENCE_END)"/>
<xsl:template match="/*">
<xsl:for-each select=".//TOKEN[#DOUBLE='YES'][key('primary_tokens',concat(#SENTENCE_BEGIN,'|',#SENTENCE_END))]">
<xsl:if test="key('primary_tokens',concat(#SENTENCE_BEGIN,'|',#SENTENCE_END))[#BEGIN > current()/#BEGIN]">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Fiddle: http://xsltfiddle.liberty-development.net/gWmuiJ8
Sorry I'm totally new to RapidMiner and only made the basic tutorial.
I have a dataset like
MatchID Value1 Value2 Value3
1 5 1 2
1 4.5 1.5 2
...
and would like to know if there is a possibilty to get the highest value per column (for example Value1) and make further calculations with it (generate attributes).
Thank you.
There are lots of ways as it happens. Here's one using the Aggregate operator to find the maxima, Join to join this to the original and Generate Attributes to do some calculating.
<?xml version="1.0" encoding="UTF-8"?><process version="7.2.003">
<context>
<input/>
<output/>
<macros/>
</context>
<operator activated="true" class="process" compatibility="7.2.003" expanded="true" name="Process">
<process expanded="true">
<operator activated="true" class="retrieve" compatibility="7.2.003" expanded="true" height="68" name="Retrieve Iris" width="90" x="45" y="34">
<parameter key="repository_entry" value="//Samples/data/Iris"/>
</operator>
<operator activated="true" class="aggregate" compatibility="7.2.003" expanded="true" height="82" name="Aggregate" width="90" x="179" y="34">
<parameter key="use_default_aggregation" value="true"/>
<parameter key="default_aggregation_function" value="maximum"/>
<list key="aggregation_attributes"/>
</operator>
<operator activated="true" class="join" compatibility="7.2.003" expanded="true" height="82" name="Join" width="90" x="313" y="34">
<parameter key="join_type" value="outer"/>
<parameter key="use_id_attribute_as_key" value="false"/>
<list key="key_attributes"/>
</operator>
<operator activated="true" class="generate_attributes" compatibility="7.2.003" expanded="true" height="82" name="Generate Attributes" width="90" x="447" y="34">
<list key="function_descriptions">
<parameter key="deltaA1" value="[maximum(a1)]-a1"/>
<parameter key="deltaA2" value="[maximum(a2)]-a2"/>
<parameter key="deltaA3" value="[maximum(a3)]-a3"/>
<parameter key="deltaA4" value="[maximum(a4)]-a4"/>
</list>
</operator>
<connect from_op="Retrieve Iris" from_port="output" to_op="Aggregate" to_port="example set input"/>
<connect from_op="Aggregate" from_port="example set output" to_op="Join" to_port="left"/>
<connect from_op="Aggregate" from_port="original" to_op="Join" to_port="right"/>
<connect from_op="Join" from_port="join" to_op="Generate Attributes" to_port="example set input"/>
<connect from_op="Generate Attributes" from_port="example set output" to_port="result 1"/>
<portSpacing port="source_input 1" spacing="0"/>
<portSpacing port="sink_result 1" spacing="0"/>
<portSpacing port="sink_result 2" spacing="0"/>
</process>
</operator>
</process>
Another way is to use the Extract Macro operator with the statistics setting max. This stores the maximum for a given attribute as a macro value, which then can be used, e.g. in Generate Attributes.
The advantage is that you don't modify the original dataset and don't have to use a join or multiply operator.
<?xml version="1.0" encoding="UTF-8"?><process version="7.5.000">
<context>
<input/>
<output/>
<macros/>
</context>
<operator activated="true" class="process" compatibility="7.5.000" expanded="true" name="Process">
<process expanded="true">
<operator activated="true" class="retrieve" compatibility="7.5.000" expanded="true" height="68" name="Retrieve Iris" width="90" x="45" y="34">
<parameter key="repository_entry" value="//Samples/data/Iris"/>
</operator>
<operator activated="true" class="extract_macro" compatibility="7.5.000" expanded="true" height="68" name="Extract Macro" width="90" x="179" y="34">
<parameter key="macro" value="maxA1"/>
<parameter key="macro_type" value="statistics"/>
<parameter key="statistics" value="max"/>
<parameter key="attribute_name" value="a1"/>
<list key="additional_macros"/>
<description align="center" color="transparent" colored="false" width="126">extract maximum of attribute a1 and store it in a macro</description>
</operator>
<operator activated="true" class="generate_attributes" compatibility="7.5.000" expanded="true" height="82" name="Generate Attributes" width="90" x="313" y="34">
<list key="function_descriptions">
<parameter key="DifferenceA1" value="parse(%{maxA1})-a1"/>
</list>
<description align="center" color="transparent" colored="false" width="126">calculate the difference of a1 from the maximum using the macro value</description>
</operator>
<connect from_op="Retrieve Iris" from_port="output" to_op="Extract Macro" to_port="example set"/>
<connect from_op="Extract Macro" from_port="example set" to_op="Generate Attributes" to_port="example set input"/>
<connect from_op="Generate Attributes" from_port="example set output" to_port="result 1"/>
<portSpacing port="source_input 1" spacing="0"/>
<portSpacing port="sink_result 1" spacing="0"/>
<portSpacing port="sink_result 2" spacing="0"/>
</process>
</operator>
</process>
Hint: since macro values are stored as text, you first have to parse them to use their numerical value.
A third option is to Sort the example set and only keep the example with the maximum value with a Filter Example Range operator. This comes in handy, if you are mostly interested in the values of other attributes, when a certain attribute is maximal.
<?xml version="1.0" encoding="UTF-8"?><process version="7.5.000">
<context>
<input/>
<output/>
<macros/>
</context>
<operator activated="true" class="process" compatibility="7.5.000" expanded="true" name="Process">
<process expanded="true">
<operator activated="true" class="retrieve" compatibility="7.5.000" expanded="true" height="68" name="Retrieve Iris" width="90" x="45" y="34">
<parameter key="repository_entry" value="//Samples/data/Iris"/>
</operator>
<operator activated="true" class="sort" compatibility="7.5.000" expanded="true" height="82" name="Sort" width="90" x="179" y="34">
<parameter key="attribute_name" value="a1"/>
<parameter key="sorting_direction" value="decreasing"/>
<description align="center" color="transparent" colored="false" width="126">sorting the example set on a1 decreasing</description>
</operator>
<operator activated="true" class="filter_example_range" compatibility="7.5.000" expanded="true" height="82" name="Filter Example Range" width="90" x="313" y="34">
<parameter key="first_example" value="1"/>
<parameter key="last_example" value="1"/>
<description align="center" color="transparent" colored="false" width="126">only keeping the first example, which has the maximum for a1</description>
</operator>
<connect from_op="Retrieve Iris" from_port="output" to_op="Sort" to_port="example set input"/>
<connect from_op="Sort" from_port="example set output" to_op="Filter Example Range" to_port="example set input"/>
<connect from_op="Filter Example Range" from_port="example set output" to_port="result 1"/>
<portSpacing port="source_input 1" spacing="0"/>
<portSpacing port="sink_result 1" spacing="0"/>
<portSpacing port="sink_result 2" spacing="0"/>
</process>
</operator>
</process>
I want to create a SonarQube XPath custom rule that detects (with SSLR java toolkit) all classes that do not declare a given method. I hoped to be able to do it with [not(contains(...))], but I'm stuck.
For instance, how can I detect all classes that do not declare the public String toString() method ?
//typeDeclaration//classDeclaration (that do not contain a memberDecl of type String, that has an IDENTIFIER with value "toString" and has no formal parameters)
Here follows a java example class containing the method (this one should not match the XPath expression)
public class Example {
public String toString() {
return "";
}
}
Here follows the XML code corresponding to the AST of the Example java class.
<compilationUnit tokenValue="public" tokenLine="1" tokenColumn="0">
<typeDeclaration tokenValue="public" tokenLine="1" tokenColumn="0">
<modifier tokenValue="public" tokenLine="1" tokenColumn="0">
<PUBLIC tokenValue="public" tokenLine="1" tokenColumn="0">
<TOKEN tokenValue="public" tokenLine="1" tokenColumn="0"/>
</PUBLIC>
</modifier>
<classDeclaration tokenValue="class" tokenLine="1" tokenColumn="7">
<CLASS tokenValue="class" tokenLine="1" tokenColumn="7">
<TOKEN tokenValue="class" tokenLine="1" tokenColumn="7"/>
</CLASS>
<IDENTIFIER tokenValue="Example" tokenLine="1" tokenColumn="13">
<TOKEN tokenValue="Example" tokenLine="1" tokenColumn="13"/>
</IDENTIFIER>
<classBody tokenValue="{" tokenLine="1" tokenColumn="21">
<LWING tokenValue="{" tokenLine="1" tokenColumn="21">
<TOKEN tokenValue="{" tokenLine="1" tokenColumn="21"/>
</LWING>
<classBodyDeclaration tokenValue="public" tokenLine="2" tokenColumn="2">
<modifier tokenValue="public" tokenLine="2" tokenColumn="2">
<PUBLIC tokenValue="public" tokenLine="2" tokenColumn="2">
<TOKEN tokenValue="public" tokenLine="2" tokenColumn="2"/>
</PUBLIC>
</modifier>
<memberDecl tokenValue="String" tokenLine="2" tokenColumn="9">
<type tokenValue="String" tokenLine="2" tokenColumn="9">
<classType tokenValue="String" tokenLine="2" tokenColumn="9">
<IDENTIFIER tokenValue="String" tokenLine="2" tokenColumn="9">
<TOKEN tokenValue="String" tokenLine="2" tokenColumn="9"/>
</IDENTIFIER>
</classType>
</type>
<IDENTIFIER tokenValue="toString" tokenLine="2" tokenColumn="16">
<TOKEN tokenValue="toString" tokenLine="2" tokenColumn="16"/>
</IDENTIFIER>
<methodDeclaratorRest tokenValue="(" tokenLine="2" tokenColumn="24">
<formalParameters tokenValue="(" tokenLine="2" tokenColumn="24">
<LPAR tokenValue="(" tokenLine="2" tokenColumn="24">
<TOKEN tokenValue="(" tokenLine="2" tokenColumn="24"/>
</LPAR>
<RPAR tokenValue=")" tokenLine="2" tokenColumn="25">
<TOKEN tokenValue=")" tokenLine="2" tokenColumn="25"/>
</RPAR>
</formalParameters>
<methodBody tokenValue="{" tokenLine="2" tokenColumn="27">
<block tokenValue="{" tokenLine="2" tokenColumn="27">
<LWING tokenValue="{" tokenLine="2" tokenColumn="27">
<TOKEN tokenValue="{" tokenLine="2" tokenColumn="27"/>
</LWING>
<blockStatements tokenValue="return" tokenLine="3" tokenColumn="4">
<blockStatement tokenValue="return" tokenLine="3" tokenColumn="4">
<statement tokenValue="return" tokenLine="3" tokenColumn="4">
<returnStatement tokenValue="return" tokenLine="3" tokenColumn="4">
<RETURN tokenValue="return" tokenLine="3" tokenColumn="4">
<TOKEN tokenValue="return" tokenLine="3" tokenColumn="4"/>
</RETURN>
<expression tokenValue="""" tokenLine="3" tokenColumn="11">
<primary tokenValue="""" tokenLine="3" tokenColumn="11">
<literal tokenValue="""" tokenLine="3" tokenColumn="11">
<LITERAL tokenValue="""" tokenLine="3" tokenColumn="11">
<TOKEN tokenValue="""" tokenLine="3" tokenColumn="11"/>
</LITERAL>
</literal>
</primary>
</expression>
<SEMI tokenValue=";" tokenLine="3" tokenColumn="13">
<TOKEN tokenValue=";" tokenLine="3" tokenColumn="13"/>
</SEMI>
</returnStatement>
</statement>
</blockStatement>
</blockStatements>
<RWING tokenValue="}" tokenLine="4" tokenColumn="2">
<TOKEN tokenValue="}" tokenLine="4" tokenColumn="2"/>
</RWING>
</block>
</methodBody>
</methodDeclaratorRest>
</memberDecl>
</classBodyDeclaration>
<RWING tokenValue="}" tokenLine="5" tokenColumn="0">
<TOKEN tokenValue="}" tokenLine="5" tokenColumn="0"/>
</RWING>
</classBody>
</classDeclaration>
</typeDeclaration>
<EOF tokenValue="" tokenLine="5" tokenColumn="1"/>
</compilationUnit>
Thank you in advance.
Here is the solution to my own question :
//classBody[not(//memberDecl[type[#tokenValue='String'] and IDENTIFIER[#tokenValue='toString'] and methodDeclaratorRest/formalParameters[not(formalParameterDecls)]])]
I have a XPath 2.0 query (which seems to be ok and which returns the node I expect it to return) however, but I need to have it written in XPath 1.0. Is it possible and if yes how can I do it ?
Info :
What i want to do is to concatenate the tokenValue of all IDENTIFIER and DOT nodes below qualifiedIdentifier and select the qualifiedIdentifier nodes if this concatenation results in a String which starts with "another.pkg".
The XPath 2.0 query :
//importDeclaration/qualifiedIdentifier[starts-with(string-join(descendant::*/*/#tokenValue,''),'another.pkg')]
The xml :
<compilationUnit tokenValue="package" tokenLine="1" tokenColumn="0">
<packageDeclaration tokenValue="package" tokenLine="1" tokenColumn="0">
<PACKAGE tokenValue="package" tokenLine="1" tokenColumn="0">
<TOKEN tokenValue="package" tokenLine="1" tokenColumn="0"/>
</PACKAGE>
<qualifiedIdentifier tokenValue="my" tokenLine="1" tokenColumn="8">
<IDENTIFIER tokenValue="my" tokenLine="1" tokenColumn="8">
<TOKEN tokenValue="my" tokenLine="1" tokenColumn="8"/>
</IDENTIFIER>
<DOT tokenValue="." tokenLine="1" tokenColumn="10">
<TOKEN tokenValue="." tokenLine="1" tokenColumn="10"/>
</DOT>
<IDENTIFIER tokenValue="pkg" tokenLine="1" tokenColumn="11">
<TOKEN tokenValue="pkg" tokenLine="1" tokenColumn="11"/>
</IDENTIFIER>
</qualifiedIdentifier>
<SEMI tokenValue=";" tokenLine="1" tokenColumn="14">
<TOKEN tokenValue=";" tokenLine="1" tokenColumn="14"/>
</SEMI>
</packageDeclaration>
<importDeclaration tokenValue="import" tokenLine="3" tokenColumn="0">
<IMPORT tokenValue="import" tokenLine="3" tokenColumn="0">
<TOKEN tokenValue="import" tokenLine="3" tokenColumn="0"/>
</IMPORT>
<qualifiedIdentifier tokenValue="another" tokenLine="3" tokenColumn="7">
<IDENTIFIER tokenValue="another" tokenLine="3" tokenColumn="7">
<TOKEN tokenValue="another" tokenLine="3" tokenColumn="7"/>
</IDENTIFIER>
<DOT tokenValue="." tokenLine="3" tokenColumn="14">
<TOKEN tokenValue="." tokenLine="3" tokenColumn="14"/>
</DOT>
<IDENTIFIER tokenValue="pkg" tokenLine="3" tokenColumn="15">
<TOKEN tokenValue="pkg" tokenLine="3" tokenColumn="15"/>
</IDENTIFIER>
<DOT tokenValue="." tokenLine="3" tokenColumn="18">
<TOKEN tokenValue="." tokenLine="3" tokenColumn="18"/>
</DOT>
<IDENTIFIER tokenValue="AnotherClass" tokenLine="3" tokenColumn="19">
<TOKEN tokenValue="AnotherClass" tokenLine="3" tokenColumn="19"/>
</IDENTIFIER>
</qualifiedIdentifier>
<SEMI tokenValue=";" tokenLine="3" tokenColumn="31">
<TOKEN tokenValue=";" tokenLine="3" tokenColumn="31"/>
</SEMI>
</importDeclaration>
<typeDeclaration tokenValue="public" tokenLine="5" tokenColumn="0">
<modifier tokenValue="public" tokenLine="5" tokenColumn="0">
<PUBLIC tokenValue="public" tokenLine="5" tokenColumn="0">
<TOKEN tokenValue="public" tokenLine="5" tokenColumn="0"/>
</PUBLIC>
</modifier>
<classDeclaration tokenValue="class" tokenLine="5" tokenColumn="7">
<CLASS tokenValue="class" tokenLine="5" tokenColumn="7">
<TOKEN tokenValue="class" tokenLine="5" tokenColumn="7"/>
</CLASS>
<IDENTIFIER tokenValue="AClass" tokenLine="5" tokenColumn="13">
<TOKEN tokenValue="AClass" tokenLine="5" tokenColumn="13"/>
</IDENTIFIER>
<classBody tokenValue="{" tokenLine="5" tokenColumn="20">
<LWING tokenValue="{" tokenLine="5" tokenColumn="20">
<TOKEN tokenValue="{" tokenLine="5" tokenColumn="20"/>
</LWING>
<RWING tokenValue="}" tokenLine="6" tokenColumn="0">
<TOKEN tokenValue="}" tokenLine="6" tokenColumn="0"/>
</RWING>
</classBody>
</classDeclaration>
</typeDeclaration>
<EOF tokenValue="" tokenLine="6" tokenColumn="1"/>
</compilationUnit>
Thank you in advance !
I don't think there's a way to do it in XPath 1.0 that's as general as the 2.0 version, you'd have to be much more specific, e.g. check if the first three tokens are another, . and pkg respectively
//importDeclaration/qualifiedIdentifier[*[1]/*/#tokenValue = 'another']
[*[2]/*/#tokenValue = '.']
[*[3]/*/#tokenValue = 'pkg']
This is slightly stricter than your 2.0 version, to be exactly equivalent you'd have to check that the third token starts with pkg instead of being equal to pkg (allowing "another.pkgfoo", for example, though this may not in fact be desirable).
If the tokenization is always the same, you can just concatenate the first three tokens:
//importDeclaration/qualifiedIdentifier[concat((.//*/*/#tokenValue)[1],
(.//*/*/#tokenValue)[2],
(.//*/*/#tokenValue)[3])='another.pkg']
IF I use this schema:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="Chick">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="count" type="xsd:decimal" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
With this wsdl:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.org/test/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="test"
xmlns:chi="chick"
targetNamespace="http://www.example.org/test/">
<wsdl:types>
<xsd:schema targetNamespace="http://www.example.org/test/">
<xsd:include schemaLocation="testschema.xsd"></xsd:include>
<xsd:include id="ada" schemaLocation="testschema.xsd" />
<xsd:element name="doTheRightThing">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Chick" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="doTheRightThingResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="out" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="doTheRightThingRequest">
<wsdl:part element="tns:doTheRightThing" name="parameters" />
</wsdl:message>
<wsdl:message name="doTheRightThingResponse">
<wsdl:part element="tns:doTheRightThingResponse" name="parameters" />
</wsdl:message>
<wsdl:portType name="test">
<wsdl:operation name="doTheRightThing">
<wsdl:input message="tns:doTheRightThingRequest" />
<wsdl:output message="tns:doTheRightThingResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="testSOAP" type="tns:test">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="doTheRightThing">
<soap:operation
soapAction="http://www.example.org/test/doTheRightThing" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="test">
<wsdl:port binding="tns:testSOAP" name="testSOAP">
<soap:address location="http://www.example.org/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I get this error message:
Error building the Schema Type system for the WSDL:
D:\Oracle\Middleware_11.1.1.6.0\user_projects\domains\osb_cookbook_domain\test:0: error: src-resolve.a: Could not find element 'Chick'. Do you mean to refer to the element named Chick#http://www.example.org/test/ (in testschema)?
If I change this line in wsdl:
<xsd:element ref="Chick" />
to this:
<xsd:element ref="tns:Chick" />
I could not deploy, OEPE returns this error message:
The WSDL is not semantically valid: error: src-resolve: element 'Chick#http://www.example.org/test/' not found..
Is this a bug?
Patch 14003546 solved this issue:
WSDL WITH EMBEDDED SCHEMA INCLUDE TO NO-NAMESPACE FAILS VALIDATION