アプリケーションのXMLファイルの検証に複数のXMLスキーマファイルを使用するXML検証サービスを開発しています。XMLスキーマファイルはインポートを多用します。そのため、名前空間をスキーマ定義(ファイルの場所)に関連付けるサービスが必要です。
各XML名前空間は、個別のXSDで定義されます。
schemaLocation属性を使用してスキーマをファイルに接続できることはわかっていますが、それには多くの相対パスを使用する必要があり、任意のプロジェクト構造ではうまく機能しません。
<-- schema.xsd -->
<xsd:import namespace="urn.my.namespace" schemaLocation="..."/>
<-- actual.xml -->
<root xmlns="urn.my.namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn.my.namespace schema.xsd">
</root>
バンドル全体をウォークスルーし、xsdファイルを検出し、それらの名前空間(ファイルの場所の関連付け)を他のXMLサービスで使用できるある種のレジストリに登録するサービスを作成したいと思います。
私のSymfonyプロジェクトの構造は次のとおりです。
AbcBundle/
Resources/config/services.xml
Resources/xsd/
schema.xsd
ns1.xsd
ns2.xsd
...
AbcBundle.php
XyzBundle/
[same structre]
使用予定:
$nsLocator = $container->get('xml.ns_locator');
$nsLocator->getNamespaceMap();
/* returns array(
'urn:my:ns1' => '/realpath/to/ns1.xsd',
'urn:my:ns2' => '/otherpath/to/ns2.xsd',
*/
$ nsLocatorは、Bundle / Resources /xsd/ディレクトリからそのマップを自動的に構築する必要があります。Symfonyがバンドル/コマンドまたはバンドル/コントローラーをスタックに登録する方法が好きです。
カーネルに接続し、すべてのバンドルが登録されると、すべてのXSDをスキャンしてマップを作成する、ある種のイベントリスナーについて考えていました。このようにすると、キャッシュが必要になるため、新しいリクエストまたはコマンドが実行されるたびにすべてのファイルが再スキャンされることはありません。
そのコンポーネントをビルドしてカーネルにフックするにはどうすればよいですか?このコンポーネントの正しい接続ポイントはどこにありますか?それは一般的に良いアプローチですか?