Search code examples
xmlsonarqubexpath-1.0

Range in XPATH 1.0


I'm writing a custom xml rule for SonarQube with XPath 1.0.

The parent version cannot be lower than 4.12.*

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>xpto.micronaut</groupId>
        <artifactId>microservice-bom</artifactId>
        <version>4.8.0.RC</version>
    </parent>

    <groupId>br.com.xpto</groupId>
    <artifactId>teste-pipe</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <build>
        <finalName>${pom.artifactId}-${pom.version}</finalName>
    <pluginManagement>
        <plugins>
                <plugin>
                    <groupId>org.sonarsource.scanner.maven</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>3.9.0.2155</version>
                </plugin>
        </plugins>
    </pluginManagement>
    </build>
</project>

XPath 1.0:


/project/parent/version[starts-with(text(), '4.11.')] |
/project/parent/version[starts-with(text(), '4.10.')] |
/project/parent/version[starts-with(text(), '4.9.')] |
/project/parent/version[starts-with(text(), '4.8.')] |
/project/parent/version[starts-with(text(), '4.7.')] |
/project/parent/version[starts-with(text(), '4.6.')] |
/project/parent/version[starts-with(text(), '4.5.')] |
/project/parent/version[starts-with(text(), '4.4.')] |
/project/parent/version[starts-with(text(), '4.3.')] |
/project/parent/version[starts-with(text(), '4.2.')] 

This XPath works, but would there be a way to simplify it?


Solution

  • You can match on the leading 4., and then take the text after that, but before the next dot character, and parse it as a number. Then you can check if that number is greater than or equal to 2 and less than or equal to 11.

    /project/parent/version[starts-with(text(), '4.') and number(substring-before(substring-after(text(), '.'), '.')) >= 2 and number(substring-before(substring-after(text(), '.'), '.')) <= 11]