![]() |
![]() |
[[FrontPage]]
* rngomでXMLSchemaのDatatypeLibraryを使う [#z66b4e28]
** rngom とは [#yb7f7ea2]
[[rngom>https://rngom.dev.java.net/]] (RelaxNG Object Model) は,RelaxNG のスキーマを扱うツールを作るためのライブラリです.rngom は,[[Jing>http://www.thaiopensource.com/relaxng/jing.html]]という,RelaxNGの validator をベースに開発されています.
私は,rngom で XMLSchema の datatype library を使おうとしてはまったので,その解決方法のメモです.
''以下は,試行錯誤の結果,見つけた解決法です.誤りが含まれている可能性があります''
** 問題 [#nf22b0e2]
rngom で XMLSchema の datatype library を使うには,[[xsdlib>https://msv.dev.java.net/servlets/ProjectDocumentList?folderID=101&expandFolder=101&folderID=100]] が必要です.xsdlib.jar を CLASSPATH に追加することで,利用可能になります.
しかし,単にこれを使っても,XMLSchema の datatype を利用できませんでした.
制約チェックをして,パースする場合,[[RNGOM User's Guide>https://rngom.dev.java.net/nonav/doc/users-guide.html]] によると,次のようになります.
import org.kohsuke.rngom.ast.util.CheckingSchemaBuilder;
Parseable parseable = ...;
YourParsedPattern = (YourParsedPattern)parseable.parse(new CheckingSchemaBuilder(schemaBuilder,errorHandler));
もっと,具体的なコードで書くと,例えば,次のようになります.
import org.kohsuke.rngom.ast.util.CheckingSchemaBuilder;
import org.kohsuke.rngom.binary.SchemaBuilderImpl;
import org.kohsuke.rngom.parse.Parseable;
import org.kohsuke.rngom.parse.xml.SAXParseable;
Parseable parseable = new SAXParseable(source, errorHandler);
ParsedPattern = parseable.parse(new CheckingSchemaBuilder(new SchemaBuilderImpl() ,errorHandler));
しかし,このコードでは,xsdlib.jar があっても,XMLSchema の datatype が使えません.
** 原因と解決法 [#t301bab9]
datatype を定義するには,org.relaxng.datatype.DatatypeLibrary や,org.relaxng.datatype.DatatypeLibraryFactory を実装します.
datatype を識別するURIから適切な DatatypeLibrary を返すのは,DatatypeLibraryFactory の実装の仕事です.
問題は,SchemaBuilderImpl です.引数が ErrorHandler のみのコンストラクタで構築すると,コンストラクタは,DatatypeLibraryFactory の実装として org.kohsuke.rngom.dt.builtin.BuiltinDatatypeLibraryFactory を使います.
ところが,org.kohsuke.rngom.dt.builtin.BuiltinDatatypeLibraryFactory は,XMLSchema の datatype の URI (http://www.w3.org/2001/XMLSchema-datatypes) を受け付けません.
次のような実装になっているからです.
public DatatypeLibrary createDatatypeLibrary(String uri) {
if (uri.equals(""))
return builtinDatatypeLibrary;
if (uri.equals(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_DATATYPES))
return compatibilityDatatypeLibrary;
return null;
}
代わりに,org.relaxng.datatype.helpers.DatatypeLibraryLoader を使えば,CLASSPATH から,META-INF/services/org.relaxng.datatype.DatatypeLibraryFactory を探して,その内容を元にして org.relaxng.datatype.DatatypeLibraryFactory の実装を見つけてくれるので,xsdlib.jar が提供する XMLSchema の datatype library を使うことが出来ます.
CheckingSchemaBuilder も内部で SchemaBuilderImpl を使っているので,こちらにもDatatypeLibraryFactory を渡してやる必要があります.
コードは,次のようになります.
import org.kohsuke.rngom.ast.builder.SchemaBuilder;
import org.kohsuke.rngom.ast.om.ParsedPattern;
import org.kohsuke.rngom.ast.util.CheckingSchemaBuilder;
import org.kohsuke.rngom.binary.SchemaBuilderImpl;
import org.kohsuke.rngom.binary.SchemaPatternBuilder;
import org.kohsuke.rngom.parse.Parseable;
import org.relaxng.datatype.DatatypeLibraryFactory;
import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
import org.xml.sax.ErrorHandler;
...
ErrorHandler errorHandler = ...;
Parseable parseable = ...;
DatatypeLibraryFactory datatypeLibraryFactory = new DatatypeLibraryLoader();
SchemaBuilder schemaBuilder = new SchemaBuilderImpl(errorHandler, datatypeLibraryFactory, new SchemaPatternBuilder());
ParsedPattern pattern = parseable.parse(new CheckingSchemaBuilder(schemaBuilder, errorHandler, datatypeLibraryFactory));
** 参考資料 [#h7d0ca48]
- [[RELAX NG Pluggable Datatype Libraries>http://www.thaiopensource.com/relaxng/pluggable-datatypes.html]]
- [[IBM dW : XML : RELAX NGとカスタム・データ型ライブラリ - Japan>http://www-6.ibm.com/jp/developerworks/xml/050204/j_x-custyp.html]]