簡體   English   中英

我怎樣才能簡化這個解析方法?

[英]How can I simplify this parsing method?

我正在編寫代碼以從文件中解組 XML。 我事先不知道 XML 基於哪個模式,因此我嘗試使用不同 Jaxb2Marshaller 實例形式的多個模式對其進行解組。

該方法需要:

  1. 嘗試用每個編組器解組 XML
  2. 如果成功,返回結果 object
  3. 如果失敗,嘗試下一個編組器
  4. 如果所有編組器都失敗,則拋出最后一個錯誤消息的異常

這是當前代碼:

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)。 該塊要么返回結果 object,要么返回 lastErrorMessage,在迭代下面需要它來拋出 MyException。

我能想到的唯一解決方案是創建一些人為的結果 class,其中包含結果 object 或錯誤消息,但感覺很笨拙。 還有其他見解嗎?

我想要像這樣的粒度方法:

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

但是附加的Result類是冗長而且笨拙的:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM