Failed to compile XPath expression - Unable to resolve XML namespace prefix not declared in the root element

Sonarsource product versions

SonarQube - Community Edition, Version 7.9.2 (build 30863)
SonarQube Scanner - 4.0.0.1744
SonarXML Plugin - 2.0.1 (build 2020)

Error observed

ERROR: Unable to execute rule xml:custom_xpath_rule on file:///jenkins/workspace/project/sample.xml
java.lang.IllegalStateException: Failed to compile XPath expression based on user-provided parameter [/ser:proxyServiceEntry/ser:endpointConfig/tran:provider-specific/jms:inbound-properties/jms:XA-required[text()='false']]
	at org.sonar.plugins.xml.checks.XPathCheck.getXPathExpression(XPathCheck.java:114)
	at org.sonar.plugins.xml.checks.XPathCheck.scanFile(XPathCheck.java:70)
	at org.sonarsource.analyzer.commons.xml.checks.SonarXmlCheck.scanFile(SonarXmlCheck.java:44)
	at org.sonar.plugins.xml.XmlSensor.runCheck(XmlSensor.java:127)
	at org.sonar.plugins.xml.XmlSensor.lambda$runChecks$0(XmlSensor.java:121)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at org.sonar.plugins.xml.XmlSensor.runChecks(XmlSensor.java:121)
	at org.sonar.plugins.xml.XmlSensor.scanFile(XmlSensor.java:111)
	at org.sonar.plugins.xml.XmlSensor.execute(XmlSensor.java:92)
	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:400)
	at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:395)
	at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:358)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:141)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
	at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
	at com.sun.proxy.$Proxy0.execute(Unknown Source)
	at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:185)
	at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:137)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
	at org.sonarsource.scanner.cli.Main.main(Main.java:61)
Caused by: javax.xml.xpath.XPathExpressionException: javax.xml.transform.TransformerException: Prefix must resolve to a namespace: tran
	at java.xml/com.sun.org.apache.xpath.internal.jaxp.XPathImpl.compile(Unknown Source)
	at org.sonar.plugins.xml.checks.XPathCheck.getXPathExpression(XPathCheck.java:112)
	... 46 common frames omitted
Caused by: javax.xml.transform.TransformerException: Prefix must resolve to a namespace: tran
	at java.xml/com.sun.org.apache.xpath.internal.compiler.XPathParser.error(Unknown Source)
	at java.xml/com.sun.org.apache.xpath.internal.compiler.Lexer.mapNSTokens(Unknown Source)
	at java.xml/com.sun.org.apache.xpath.internal.compiler.Lexer.tokenize(Unknown Source)
	at java.xml/com.sun.org.apache.xpath.internal.compiler.Lexer.tokenize(Unknown Source)
	at java.xml/com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(Unknown Source)
	at java.xml/com.sun.org.apache.xpath.internal.XPath.<init>(Unknown Source)
	at java.xml/com.sun.org.apache.xpath.internal.XPath.<init>(Unknown Source)
	... 48 common frames omitted

Steps to reproduce

Validate Xpath with prefix whose namespace is declared in the child tag & not in the root tag.
In below example, refering to “jms” prefix, which is not declared in the root element.

<?xml version="1.0" encoding="UTF-8"?>
<ser:proxyServiceEntry xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:oper="http://xmlns.oracle.com/servicebus/proxy/operations" xmlns:oper1="http://xmlns.oracle.com/servicebus/operations" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ser:endpointConfig xmlns:jms="http://www.bea.com/wli/sb/transports/jms" xmlns:con1="http://www.bea.com/wli/sb/stages/transform/config" xmlns:con="http://www.bea.com/wli/sb/pipeline/config" xmlns:http="http://www.bea.com/wli/sb/transports/http" xmlns:env="http://www.bea.com/wli/config/env" xmlns:con4="http://www.bea.com/wli/sb/stages/publish/config" xmlns:tran="http://www.bea.com/wli/sb/transports" xmlns:con2="http://www.bea.com/wli/sb/stages/config" xmlns:con3="http://www.bea.com/wli/sb/stages/logging/config">
        <tran:provider-id>jms</tran:provider-id>
        <tran:inbound>true</tran:inbound>
        <tran:URI>
            <env:value>jms:///jms-queue</env:value>
        </tran:URI>
        <tran:inbound-properties/>
        <tran:all-headers>true</tran:all-headers>
        <tran:provider-specific>
            <jms:is-queue>true</jms:is-queue>
            <jms:is-secure>false</jms:is-secure>
            <jms:inbound-properties>
                <jms:response-required>false</jms:response-required>
                <jms:XA-required>true</jms:XA-required>
                <jms:transaction-timeout>600</jms:transaction-timeout>
            </jms:inbound-properties>
            <jms:dispatch-policy>default</jms:dispatch-policy>
            <jms:request-encoding>UTF-8</jms:request-encoding>
            <jms:jndi-timeout>0</jms:jndi-timeout>
        </tran:provider-specific>
    </ser:endpointConfig>
</ser:proxyServiceEntry>

Potential workaround

Move/Copy the namespace prefix declaration to the root element as workaround.

Expected Solution

The XML parser must be able to traverse the entire XML to resolve the namespace prefix declartion while evaluating the XPath.

You cannot use a namespace prefix in the XPath expression: what would be the namespace associated to the prefix? Different XML files may use the same prefix for different namespaces.

You should specify the namespace for each element name in the XPath expression.
For example:

//*[namespace-uri()='http://www.bea.com/wli/sb/transports/jms' and local-name()='inbound-properties']

You may also explicitly ignore the namespace in the XPath expression. The following expression would match all elements named inbound-properties whatever their namespace:

//*[local-name()='inbound-properties']

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