我已经构建了一个应用程序,该应用程序使用schematron验证和xml。
这是代码:
import net.sf.saxon.s9api.*;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class ValidateSchema {
public static void main(String[] args) {
try {
Processor processor = new Processor(false);
XsltCompiler compiler = processor.newXsltCompiler();
XsltExecutable xslt = compiler.compile(new StreamSource(
new File("target/example.xsl")
));
XsltTransformer transformer = xslt.load();
transformer.setSource(new StreamSource(new File("example.xml")));
XdmDestination chainResult = new XdmDestination();
transformer.setDestination(chainResult);
transformer.transform();
List<String> errorList = new ArrayList<>();
XdmNode rootnode = chainResult.getXdmNode();
for (XdmNode node : rootnode.children().iterator().next().children()) {
if(!"failed-assert".equals(node.getNodeName().getLocalName())) continue;
String res = node.children().iterator().next().getStringValue();
errorList.add(trim(res));
}
for (String s : errorList) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String trim(String s) {
s = s.replaceAll("n", "").replaceAll("t", " ");
while (s.indexOf(" ") != -1) {
s = s.replaceAll(" ", " ");
}
return s.trim();
}
}
当我尝试运行应用程序时,它会给我错误:java.lang.NullPointerException在ValidateSchema.main(ValidateSchema.java:27(,这是一行代码:
if(!"failed-assert".equals(node.getNodeName().getLocalName())) continue;
这是我第一次建造这样的东西,我想知道如何修复它。提前感谢
您的迭代
for (XdmNode node : rootnode.children().iterator().next().children())
可能正在传递没有名称的节点(如文本节点(,因此
node.getNodeName()
返回null,因此
node.getNodeName().getLocalName()
出现NPE故障。
您可以限制children()
仅使用children(Predicates.isElement())
返回元素。
或者将循环更改为
for (XdmNode node : rootnode.children().iterator().next().children("failed-assert")) {
String res = node.children().iterator().next().getStringValue();
errorList.add(trim(res));
}
或者更简洁地说
for (XdmNode node : rootnode.select(Steps.path(*, "failed-assert")) {
errorList.add(node.select(Steps.child()).first().getStringValue());
}
我会考虑使用XPath来选择文本消息,例如,如果您在验证结果的根节点上使用XPath选择例如/*/*:failed-assert
或更好的/*/*:failed-assert => string-join(codepoints-to-string(10))
,则会得到所有失败断言消息的列表。
为xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
设置/声明名称空间并使用//svrl:failed-assert => string-join(codepoints-to-string(10))
可能更简单,但这两个示例都应该让您只使用XPath来提取错误消息。
在Java方面,它将被用作
XdmItem result = processor.newXPathCompiler.evaluateSingle("/*/*:failed-assert => string-join(codepoints-to-string(10))", rootnode);
然后可以输出CCD_ 9。