標籤:pbs sdn extra 資訊 uvc 載入 分解 event phi
編寫好XSD檔案,然後來看怎麼使用XSD檔案校正,並解析SqlMapper檔案,也就是實現doParseSqlMapperResourceWithSchema()方法。
為了實現這個功能,有兩個基本要求:
(1)相容性:需要相容mybatis的原生配置,相容有兩種層級,一種是使用DTD校正,這個前面已經說了,走原來的流程,相容性沒有問題;另一種就是走XSD校正,但也需要相容mybatis原生配置,這種相容性一方面從上面修改的XSD檔案去保證,另一方面也需要從XML的解析去保證。
(2)擴充性:修改的目的就是為了擴充性,所以擴充性也是一個基本要求。但是擴充性不是隨意性,也需要按照規範來擴充,這個規範就是自訂的XSD檔案。
為了達到這兩個基本要求,下面是我的一種思路,主要借鑒於Spring的自訂命名空間:
1、建立一個EntityResolver,讀取類路徑下指定模式的設定檔,比如:"classpath*:**/dysd-*-namespaces.ini"
2、在ini檔案中定義命名空間元資訊,如:
使用命名空間作為Section的名稱,下面的schema、parser分別表示命名空間的xsd檔案和解析器實作類別,這樣就可以根據XML中的XSD命名空間找到校正檔案,並且有一個解析入口了。
說明:
- apache的commons-configuration提供了ini格式檔案的讀取API
- Spring中使用META-INF/spring.schemas和META-INF/spring.handlers來儲存XSD檔案和解析器實作類別,這裡我修改為使用ini檔案集中配置
- 因為讀取的是所有類路徑下滿足萬用字元的ini檔案,因此可以非常簡單的擴充其它命名空間,至於在Java中具體怎麼使用XSD來校正,這裡就不細說了
我把XML的解析分解為三要素:解析上下文、解析器、被解析檔案。doParseSqlMapperResourceWithSchema()方法也很簡潔:
protected void doParseSqlMapperResourceWithSchema(Configuration configuration, Resource mapperLocation){ ISqlMapperParserContext context = new SqlMapperParserContext(configuration); XmlParserUtils.parseXml(context, mapperLocation);}
解析器介面如下:
public interface IParser<E extends IParserContext> { public void parse(E parserContext, String location); public void parse(E parserContext, String[] locationPatterns); public void parse(E parserContext, InputStream inputStream); public void parse(E parserContext, Resource resource);}
解析上下文和解析器實作類別又依次分為三個層級:
(1)通用解析上下文:
public interface IParserContext { public ProblemReporter getProblemReporter(); public EventListener getEventListener(); public SourceExtractor getSourceExtractor(); public Environment getEnvironment();}
相應層級的解析器實作類別主要負責載入被解析檔案(比如將字串萬用字元載入為Resource對象集合),保證不重複解析,保證可並發執行等。
(2)XML解析上下文
public interface IXmlParserContext extends IParserContext{ public boolean isNamespaceAware(); public DocumentLoader getDocumentLoader(); public EntityResolver getEntityResolver(); public ErrorHandler getErrorHandler(); public XmlParserDelegate getDelegate();}
相應層級的解析器實作類別主要負責將Resource轉換為Document對象,並在轉換的過程中進行校正。
(3)SqlMapper解析上下文
public interface ISqlMapperParserContext extends IXmlParserContext{ public Configuration getConfiguration();}
相應層級的解析器實作類別主要負責尋找根項目所在命名空間的解析器,並使用解析器對Document進行解析。
最終,將解析委託給ini設定檔中的SchemaSqlMapperNamespaceParser類,但是因為這個類需要在文字檔中配置,不方便有參數的建構函式,因而進一步委託給SchemaSqlMapperParserDelegate:
public class SchemaSqlMapperNamespaceParser implements INamespaceParser<ISqlMapperParserContext> { @Override public void init() { } @Override public void parse(ISqlMapperParserContext parserContext, Document document, Resource resource) { SchemaSqlMapperParserDelegate delegate = new SchemaSqlMapperParserDelegate(parserContext, document, resource); delegate.parse(); } @Override public void destory() { }}
至此,XSD校正已經完成,也已經找到XML解析入口,後續就是在SchemaSqlMapperParserDelegate中真正的解析了。
使用XSD校正Mybatis的SqlMapper設定檔(2)