我们正在尝试实现Sonar XML 插件来分析我们项目的 XHTML。我在使用 Xpath 规则和多个命名空间时遇到问题。我们想对文件运行 Xpath 检查它们是否包含多个不同的名称空间,但这似乎是不可能的。
默认情况下,Sonar 自动检测命名空间——在我们的例子中是 XML 或 XHTML 命名空间——并使用相关的模式。问题是我们在 XHTML 中使用Primefaces 标签,并且我们想使用 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 模式的一部分导入。
我在我的架构中做错了什么可能导致这种情况吗?有没有人解决过涉及声纳的类似问题?任何建议表示赞赏。