Custom XPATH rule is not displayed in the correct line


I defined a new XPATH rule for PL/I:

count(//STATEMENT[@tokenValue=‘EXEC’]//DUMMY[@tokenValue=‘SQL’]//ANY_TOKEN[@tokenValue=‘UPDATE’]|//ANY_TOKEN[@tokenValue=‘WHERE’]) < 2

With this rule I want to check if there is a Where in a Update statement. SonarLint checks it correctly, but does not show the note in the correct line:
Topaz Workbench - sonarlint


I will assume you have the same behavior in SonarQube.

I think the problem is that your XPath rule is a boolean expression. When it returns true, there is no other way for SonarQube/SonarLint than raising an issue globally to the file.
To report an issue on a specific location, your XPath expression has to select/return the actual offending node (for example here I would select the UPDATE node).


I want to check if a Update contain a Where. But if I try it with this Xpath expression

//DUMMY[@tokenValue='SQL']//ANY_TOKEN[contains(@tokenValue,'UPDATE')] and //ANY_TOKEN[contains(@tokenValue,'WHERE')]

then I get also a Boolean.

With the Xpath expression

//ANY_TOKEN[contains(@tokenValue,'UPDATE')] | //ANY_TOKEN[contains(@tokenValue,'WHERE')]

I get the following:
Topaz Workbench

But I need opposite and I don´t know how can I do it?


Try maybe?


yes I tried with the not:
//ANY_TOKEN[@tokenValue='SQL']/following-sibling::ANY_TOKEN[(position()=1 and ((contains(@tokenValue,'UPDATE') or contains(@tokenValue,'DELETE'))))]/following-sibling::ANY_TOKEN[not(contains(@tokenValue,'WHERE'))]

But I get all other sibling back.

My XML looks so:

   <DUMMY tokenValue="SQL" tokenLine="1" tokenColumn="5">
      <ANY_TOKEN tokenValue="SQL" tokenLine="1" tokenColumn="5">
        <IDENTIFIER tokenValue="SQL" tokenLine="1" tokenColumn="5"/>
      <ANY_TOKEN tokenValue="UPDATE" tokenLine="2" tokenColumn="5">
        <IDENTIFIER tokenValue="UPDATE" tokenLine="2" tokenColumn="5"/>
      <ANY_TOKEN tokenValue="TABEL" tokenLine="2" tokenColumn="12">
        <IDENTIFIER tokenValue="TABEL" tokenLine="2" tokenColumn="12"/>
      <ANY_TOKEN tokenValue="SET" tokenLine="3" tokenColumn="6">
        <IDENTIFIER tokenValue="SET" tokenLine="3" tokenColumn="6"/>
      <ANY_TOKEN tokenValue="TEST" tokenLine="3" tokenColumn="10">
        <IDENTIFIER tokenValue="TEST" tokenLine="3" tokenColumn="10"/>
      <ANY_TOKEN tokenValue="=" tokenLine="3" tokenColumn="15">
        <EQUAL tokenValue="=" tokenLine="3" tokenColumn="15"/>
      <ANY_TOKEN tokenValue="'F'" tokenLine="3" tokenColumn="16">
        <CHARACTER tokenValue="'F'" tokenLine="3" tokenColumn="16"/>
      <ANY_TOKEN tokenValue="WHERE" tokenLine="4" tokenColumn="15">
        <IDENTIFIER tokenValue="WHERE" tokenLine="4" tokenColumn="15"/>
      <ANY_TOKEN tokenValue="TEST" tokenLine="4" tokenColumn="21">
        <IDENTIFIER tokenValue="TEST" tokenLine="4" tokenColumn="21"/>
      <ANY_TOKEN tokenValue="=" tokenLine="4" tokenColumn="26">
        <EQUAL tokenValue="=" tokenLine="4" tokenColumn="26"/>
      <ANY_TOKEN tokenValue="TEST" tokenLine="4" tokenColumn="28">
        <IDENTIFIER tokenValue="TEST" tokenLine="4" tokenColumn="28"/>
      <SEMICOLON tokenValue=";" tokenLine="4" tokenColumn="32"/>

What about:

//ANY_TOKEN[@tokenValue='SQL']/following-sibling::ANY_TOKEN[(position()=1 and ((@tokenValue='UPDATE' or @tokenValue='DELETE'))) and count(following-sibling::ANY_TOKEN[@tokenValue='WHERE']) = 0]

Thank you for your Support, it works.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.