【问题标题】:Validating an xml with schematron null pointer exception使用 schematron 空指针异常验证 xml
【发布时间】:2022-01-20 09:59:36
【问题描述】:

我已经构建了一个使用 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;

这是我第一次构建这样的东西,我想知道如何解决这个问题。提前致谢

【问题讨论】:

  • Schematron 验证的结果是 XML,这就是您将其作为 XML 处理的原因,不是吗?考虑再次使用 XSLT(或者可能只是 XPath)来输出消息。如果您需要帮助,请向我们展示示例结果和您要提取的示例消息。

标签: java xml maven saxon schematron


【解决方案1】:

你的迭代

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());
}

【讨论】:

    【解决方案2】:

    我会考虑使用 XPath 来选择文本消息,例如如果您选择例如/*/*:failed-assert 或更好的 /*/*:failed-assert =&gt; string-join(codepoints-to-string(10)) 在验证结果的根节点上使用 XPath,您将获得所有失败断言消息的列表。

    xmlns:svrl="http://purl.oclc.org/dsdl/svrl" 设置/声明命名空间并使用//svrl:failed-assert =&gt; string-join(codepoints-to-string(10)) 可能会更简洁,但是这两个示例都应该让您开始使用XPath 来提取错误消息。

    在 Java 端将用作

    XdmItem result = processor.newXPathCompiler.evaluateSingle("/*/*:failed-assert => string-join(codepoints-to-string(10))", rootnode);
    

    然后就可以输出result.getStringValue()了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多