【问题标题】:Java SAX strategy pattern based on XSD value基于 XSD 值的 Java SAX 策略模式
【发布时间】:2015-07-29 13:37:06
【问题描述】:

如何基于 XSD 定义在 SAX 上实施策略模式?

like:
if xsd = V1 use V1Parser
if xsd = V2 use V2Parser
if xsd = V3 use V3Parser
else error

问题是我必须查看 XML 才能知道定义了哪个 XSD,但是我无法再更改解析器(我不会再开始了,因为 xsd 不是在开始时定义的/不好来自 ERM 系统的格式化 XML)。

你知道解决方法吗?

【问题讨论】:

  • 您的 VxParsers 是 SAX ContentHandler 吗?
  • 不完全是,它们是 DefaultHandler。
  • 您必须深入了解 XML 以决定采用哪个解析器? XSD 是否在根元素中定义?
  • 不,每个子树都有自己的 XSD。
  • 所以当你进入一个带有特定 XSD 的子树时,你想为那个子树使用一个特定的 DefaultHandler?

标签: java xml xsd sax strategy-pattern


【解决方案1】:

解决方案可能是使用 DefaultHandler VDispatch,它在内部将 SAX 事件委托给适当的 DefaultHandler V1、V2 或 V3。

startElement 中,VDispatch 查找相关子树的开头。根据 XSD 子树,它选择相应的处理程序 V1、V2 或 V3。

在子树中,它将所有事件转发给所选的处理程序。

在子树之外它忽略所有事件。

public class VDispatch extends DefaultHandler {
     private DefaultHandler current_;
     private int subtreeLevel_;

     public void startElement(String uri, String localName, String qName, Attributes attributes) {
          if ((current_ == null) && (subtree-is-starting)) {
              current_ = select-handler-based-on-xsd;
              subtreeLevel_ = 0;
          }
          if (current_ != null) {
              current_.startElement(uri, localName, qName, attributes);
              subtreeLevel_++;
          }
     }

     public void endElement(String uri, String localName, String qName) {
          if (current_ != null) {
              current_.endElement(uri, localName, qName);
              if (--subtreeLevel_ == 0)
                  current_ = null;
          }
     }

     // simple forwarding in all other DefaultHandler methods
     public void characters(char[] ch, int start, int length) {
          if (current_ != null)
              current_.characters(ch, start, length);
     }
}

【讨论】:

  • 感谢您提供干净的解决方案!
猜你喜欢
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
相关资源
最近更新 更多