Sonar XML插件:XPath规则和命名空间

时间:2012-08-09 17:51:21

标签: xml xpath namespaces sonarqube

我们正在尝试实施Sonar XML Plugin来分析我们项目的XHTML。我遇到了Xpath规则和多个命名空间的问题。我们希望对文件运行Xpath检查,无论它们是否包含多个不同的命名空间,但这似乎不可能。

默认情况下,Sonar会自动检测命名空间 - 在我们的例子中是XML或XHTML命名空间 - 并使用关联的模式。问题是我们在XHTML中使用Primefaces tags,我们希望使用Sonar的自定义xpath验证来检查一些特定的东西与primefaces标签。例如//p:outputPanel[not(@layout='block')来查找XML文件中的特定元素。

我们将此XPath规则放入Sonar并运行我们的检查:

mvn -f pom-xhtml.xml sonar:sonar

如果的文件中包含Primefaces标记,因此没有声明Primefaces名称空间,我们会收到以下错误:

[ERROR] [13:35:54.918] Could not analyze the file /Users/...snip.../header.xhtml
org.sonar.api.utils.SonarException: javax.xml.xpath.XPathExpressionException
    at org.sonar.plugins.xml.checks.XPathCheck.getXPathExpressionForDocument(XPathCheck.java:120) ~[na:na]
    ... snip ...
Caused by: javax.xml.xpath.XPathExpressionException: null
    at org.apache.xpath.jaxp.XPathImpl.compile(XPathImpl.java:408) ~[xalan-2.7.1.jar:na]
    at org.sonar.plugins.xml.checks.XPathCheck.getXPathExpressionForDocument(XPathCheck.java:118) ~[na:na]
    ... 40 common frames omitted
Caused by: org.apache.xpath.domapi.XPathStylesheetDOM3Exception: Prefix must resolve to a namespace: p
    ... snip ...
    ... 41 common frames omitted

此类文件的示例可能是这一行文件:

<?xml version="1.0" encoding="UTF-8"?>
<s:resource xmlns:s="http://jboss.com/products/seam/taglib" xmlns="http://www.w3.org/1999/xhtml" />

据我所知,因为Sonar正在尝试使用“p:”命名空间测试Xpath规则,所以它会在未声明该命名空间的文件上出错。我们宁愿不将所有命名空间添加到我们的所有文件中,因为任何其他原因都不需要它。

我看到Sonar可以处理自定义模式(使用sonar.xml.schemas选项),所以我创建了一个然后将所需的名称空间导入其中的模式。如果Sonar使用此模式进行分析,则可以声明Xpath检查所需的所有命名空间。

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:import namespace="http://java.sun.com/jstl/core"/>
   <xs:import namespace="http://java.sun.com/jsf/facelets"/>
   <xs:import namespace="http://java.sun.com/jsf/html"/>
   <xs:import namespace="http://jboss.com/products/seam/taglib"/>
   <xs:import namespace="http://java.sun.com/jsf/core"/>
   <xs:import namespace="http://primefaces.prime.com.tr/ui"/>
</xs:schema>

但是,当我尝试这样做时,我收到以下错误:

[ERROR] [12:59:30.197] Could not analyze the file /Users/...snip...header.xhtml
java.lang.NullPointerException: name
    at java.util.zip.ZipFile.getEntry(ZipFile.java:156) ~[na:1.6.0_33]
    ... snip ...
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352) [plexus-classworlds-2.4.jar:na]

这不是很有帮助。如果我尝试空白架构:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
</xs:schema>

然后我们回到第一个错误。因此,声纳成功指向自定义架构,但它无法正常工作。所以似乎Sonar(或Java?)无法处理导入其他名称空间作为XML模式的一部分。

我在架构中做错了可能会导致这种情况吗?有人解决了涉及声纳的类似问题吗?任何建议都表示赞赏。

1 个答案:

答案 0 :(得分:2)

嗯,这不是我想要的答案,但我们最终添加了我们需要对每个页面进行XPATH测试所需的所有命名空间声明。所以我们的短篇小说变成:

<s:resource xmlns:ui="http://java.sun.com/jsf/facelets" xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jstl/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.prime.com.tr/ui" data="#{}" contentType="#{}" fileName="#{}"/>

该页面不需要所有额外的命名空间声明,但它们使得XPath检查在Sonar中起作用。不理想,但......它有效。