我怎样才能简化这个解析方法?

How can I simplify this parsing method?

我正在编写代码以从文件中解组 XML。我事先不知道 XML 基于哪个模式,所以我尝试使用不同 Jaxb2Marshaller 实例形式的多个模式对其进行解组。

该方法需要:

  1. 尝试用每个编组器
  2. 解组XML
  3. 如果成功,return 生成的对象
  4. 如果失败,尝试下一个编组器
  5. 如果所有编组器都失败,则抛出异常并显示最后一条错误消息

这是当前代码:

private Object getObject(final byte[] data) throws MyException {
    String lastErrorMessage = "";
    for (final Jaxb2Marshaller marshaller : this.marshallers) {
        try {
            return marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(data)));
        } catch (final XmlMappingException e) {
            LOGGER.warn("Invalid XML", e);
            lastErrorMessage = e.getMessage();
        }
    }
    throw new MyException(lastErrorMessage);
}

我觉得这个方法在不同的抽象层次上做了太多事情:

但我没有找到简化它的方法。每个编组器都需要 try-catch 块(因为除了最后一个之外,我应该捕获并忽略这些 XmlMappingExceptions)。该块 return 是一个结果对象,或者是 lastErrorMessage,这是在迭代下面抛出 MyException 所必需的。

我能想到的唯一解决方案是创建一些人为的结果 class,其中包含结果对象或错误消息,但感觉很笨拙。还有其他见解吗?

我想要像这样粒度的方法:

private Object getObject(byte[] data) throws MyException {
    Result result;
    for (Jaxb2Marshaller marshaller : this.marshallers) {
        result = getObject(marshaller, data);
    }
    return handleError(result);
}

private Result getObject(Jaxb2Marshaller marshaller, byte[] data) {
    try {
        return Result.value(marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(data))));
    } catch (final XmlMappingException e) {
        LOGGER.warn("Invalid XML", e);
        return Result.error(e.getMessage());
    }
}

private Object handleError(Result result) {
    if (result.isError()) {
        throw new MyException(result.errroMessage);
    }
    else {
        return result.value;        
    }
}

但附加结果 class 冗长且笨拙:

private class Result {
    String errorMessage;
    Object value;

    static Result error(String errorMessage) {
        Result result = new Result();
        result.errorMessage = errorMessage;
        return result;
    }

    static Result value(Object value) {
        Result result = new Result();
        result.value = value;
        return result;
    }

    boolean isError() {
        return errorMessage != null;
    }
}

这个怎么样?

public class MultiUnmarshaller {

    private final List<Jaxb2Marshaller> marshallers;
    private Object value;
    private String error;

    public MultiUnmarshaller(List<Jaxb2Marshaller> marshallers) {
        this.marshallers = marshallers;
    }

    private void init() {
        error = "No marshallers available";
        value = null;
    }

    public Object getObject(byte[] data) throws MyException {
        init();
        Iterator<Jaxb2Marshaller> it = marshallers.iterator();           
        while(it.hasNext() && errorMessage != null) {
            unmarshalObject(marshaller, data);
        }
        return produceResult();
    }

    private void unmarshalObject(Jaxb2Marshaller marshaller, byte[] data) {
        try {
            value = marshaller.unmarshal(new StreamSource(new     ByteArrayInputStream(data)));
            error = null;
        } catch (final XmlMappingException e) {
            LOGGER.warn("Invalid XML", e);
            error = e.getMessage();
        }
    }

    private Object produceResult() {
        if (error == null) {
            return value;        
        }
        else {
            throw new MyException(error);
        }
    }
    
}