自动处理Symfony Bundle Resources

时间:2012-11-07 11:05:56

标签: php xml symfony xsd

我正在开发一个XML Validation服务,该服务使用多个XML Schema文件来验证我的应用程序中的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>

我想创建一个遍及bundle的服务,发现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及其堆栈的方式。

我在想某种类型的事件监听器会挂钩内核,一旦所有Bundles都被注册,它就会扫描所有XSD并创建一个映射。如果以这种方式完成,则需要缓存,因此每次执行新请求或命令时都不会重新扫描所有文件。

如何构建该组件并将其挂钩到内核中?此组件的正确连接点在哪里?这通常是一种好方法吗?

1 个答案:

答案 0 :(得分:2)

您应该能够创建一个编译器传递,该传递将在构建容器时运行(在主传递之后)。

在传递过程中,获取包列表并迭代它们以创建xsd文件列表。最后,将列表传递给您的服务。

获取捆绑包列表:

$container->getParameter('kernel.bundles')

了解更多: