如何在Java中处理与XML相关的异常?

时间:2015-08-24 20:25:47

标签: java xml xpath

我正在处理需要阅读,操作和编写XML文档的应用程序。在使用XML API时,我不得不抓住几个例外情况,而且我不确定如何处理它们。

请考虑以下代码:

public static void removeWhitespace(Document document)
{
    XPath xPath = getXPath();
    NodeList emptyTextNodes;
    try
    {
        XPathExpression expression = xPath.compile("//text()[normalize-space(.) = '']");
        emptyTextNodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
    }
    catch (XPathExpressionException e)
    {
        // How to handle this?
        return;
    }

    int nEmptyTextNodes = emptyTextNodes.getLength();
    for (int i = 0; i < nEmptyTextNodes; ++i)
    {
        Node node = emptyTextNodes.item(i);
        node.getParentNode().removeChild(node);
    }
}

The documentation for XPath#compile表示XPathExpressionException将被抛出&#34;如果表达式无法编译&#34;。但是,在这种情况下,表达式是硬编码的(大概)有效,所以这不应该发生。由于这是一个经过检查的异常,我必须处理它 - 但是我应该在catch块中做什么?

同样地,the documentation for XPathExpression#evaluate表示将抛出XPathExpressionException&#34;如果表达式无法评估&#34;。由于我认为表达式是有效的,我认为这种情况发生的唯一方法是调用者传递无效的Document。我该怎么处理?

考虑这种方法:

public static String documentToString(Document document)
{
    StringWriter writer = new StringWriter();
    try
    {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        transformer.transform(new DOMSource(document), new StreamResult(writer));
    }
    catch (TransformerException e)
    {
        // What happens now?
        return null;
    }

    String xml = writer.getBuffer().toString();
    // No need to close the StringWriter
    return xml;
}

TransformerFactory#newTransformer会抛出一个TransformerConfigurationException(会链接文档,但SO赢了不让我)&#34;当无法创建Transformer实例时#34;。怎么会发生这种情况?我该如何处理?

我可以声明抛出这些异常,但这只会将问题移到其他地方。

在哪种情况下抛出这些异常,我该如何处理它们?

2 个答案:

答案 0 :(得分:2)

  

在哪种情况下抛出这些例外

这些是javax.xml包中与XML / XPath / XSLT相关的异常的可能原因:

  • 传递给API方法的无效参数
  • 使用可选且不受实现支持的配置
  • 读取源或编写结果时的IO和编码错误
  • 解析XML文档,XSLT样式表,XPath表达式
  • 时出现语法错误
  • 执行无效操作导致的错误(例如在XPath中:在字符串或数字上调用节点集函数)
  • 任何其他运行时错误,很可能是由实现中的错误引起的
  

我应该如何处理它们?

就像你对待所有例外:

如果可以处理异常,即修复其原因或采取其他操作,则捕获它并在catch块中运行异常处理程序代码。

如果您无法处理异常,请让调用者处理它。对于已检查的异常,最简单的方法是在方法throw子句中声明它。 您还可以捕获异常以将其转换为另一种类型(另一种已检查的异常,RuntimeException甚至是Error)。如果您不希望在方法签名中包含已检查的异常,则可以使用转换为RuntimeException(例如,IllegalStateException)。

举例来说:

您的方法可能不会失败(没有磁盘IO操作,没有语法错误,所有参数都没问题等)。 您仍然无法处理异常,因此您需要将其传递给调用方。 在这两种方法的情况下,如果方法会声明XPathExpressionExceptionTransformerException,则可能会令人恼火(但仍然合理)。 如果你问我,我会抓住XPathExpressionExceptionTransformerException并将它们重新包装成IllegalStateException

答案 1 :(得分:2)

  

这不应该发生[但],我必须处理它[,所以]我应该在catch块中做什么?

如果你真的相信它不可能发生,如果你指望它不会发生,并且事实证明你错了而实际发生的例外,则意味着你的程序是有缺陷的。

这是异常的最简单的处理程序,意味着程序有缺陷:

catch (TheException ex) {
    assert false;
}

这是一个更好的:

import org.apache.log4j.Logger;
 ...
static final Logger LOGGER = ...;
 ...
catch (TheException ex) {
    LOGGER.fatal("Unexpected exception", ex);
    myApplication.makeSafeToShutdown(...);
    System.exit(1);
}