基于Eclipse-PMD的XPath问题:识别非条件语句内的Java打印语句
识别未处于条件语句内的System.out.println打印语句
需求:识别Java代码中未被IfStatement节点作为祖先包含的System.out.println打印语句。
测试用例
用例1:识别所有顶级打印语句
待检测代码:
int x = 5; int y = 10; System.out.println("The value of x is " + x); System.out.println("The value of y is " + y);
需识别代码中所有的System.out.println语句。
用例2:忽略if块内的打印语句
待检测代码:
if (x > 10) { System.out.println("x is greater than 10"); } System.out.println("This is the end of the program");
需忽略if代码块内的打印语句,仅识别第二个不在if范围内的System.out.println语句。
已尝试的无效XPath表达式
以下表达式在PMD规则设计器中测试均未达到预期效果:
- 表达式1:
//Name[@Image='System']/following-sibling::Name[@Image='out']/following-sibling::Name[@Image='println'][not(ancestor::IfStatement)]
- 表达式2:
//Name[@Image='System']/descendant-or-self::Name[@Image='println'][not(ancestor::IfStatement)]
- 表达式3:
//Name[@Image='System']/child::Name[@Image='println'][not(ancestor::IfStatement)]
- 表达式4:
//attribute::Image[.='System']/parent::Name/following-sibling::Name[attribute::Image='out']/following-sibling::Name[attribute::Image='println'][not(ancestor::IfStatement)]
- 表达式5:
//Name[@Image='System']/preceding-sibling::Name[@Image='out']/preceding-sibling::Name[@Image='println'][not(ancestor::IfStatement)]
正确的XPath表达式
结合PMD的AST结构,System.out.println对应的节点层级为MethodCall -> FieldAccess -> FieldAccess -> Name(System)、FieldAccess -> Name(out)、FieldAccess -> Name(println),正确的表达式如下:
//MethodCall[ child::FieldAccess[ child::FieldAccess[ child::Name[@Image='System'] and child::Name[@Image='out'] ] and child::Name[@Image='println'] ] and not(ancestor::IfStatement) ]
或者更简洁的写法:
//MethodCall[ FieldAccess/FieldAccess/Name[@Image='System'] and FieldAccess/Name[@Image='out'] and FieldAccess/Name[@Image='println'] and not(ancestor::IfStatement) ]
内容的提问来源于stack exchange,提问作者DeLorean
相关产品推荐
相关产品推荐

