我正在开发一个 XML 验证服务,该服务使用多个 XML 模式文件来验证我的应用程序中的 XML 文件。XML Schema 文件大量使用导入。出于这个原因,我需要一个服务,它将命名空间与它们的模式定义(文件位置)相关联。
每个 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 使用其堆栈注册 Bundle/Command 或 Bundle/Controller 的方式。
我正在考虑某种事件侦听器,它会挂接到内核中,一旦注册了所有 Bundle,它就会扫描所有 XSD 并创建一个映射。如果这样做,它将需要缓存,因此它不会在每次执行新请求或命令时重新扫描所有文件。
如何构建该组件并将其连接到内核中?该组件的正确连接点在哪里?它通常是一个好方法吗?