0

我们正在尝试实现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 模式的一部分导入。

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

4

1 回答 1

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 中工作。不理想,但......它的工作原理。

于 2012-08-21T13:51:34.260 回答