使用 xslt 转换多个 xml 模式文档 [英] Using xslt to transform multiple xml schema documents

查看:36
本文介绍了使用 xslt 转换多个 xml 模式文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多 xml 架构文档,用于描述我的应用程序的配置设置.xml 模式看起来像以下几行:

I have a number of xml schema documents which are used to describe configuration settings for my application. The xml schemas look something along the following lines:

客户端.xsd

<xsd:schema targetNamespace="http://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="Client">
        <xsd:attribute name="Host" type="xsd:string>
    </xsd:complexType>

</xsd:schema>

服务器.xsd

<xsd:schema targetNamespace="http://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="Server">
        <xsd:attribute name="Port" type="xsd:unsignedShort>
        <xsd:attribute name="MaxConnections" type="xsd:int default="32">
    </xsd:complexType>

</xsd:schema>

应用程序.xsd

<xsd:schema targetNamespace="http://www.example.com/core"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="Application">
        <xsd:attribute name="Name" type="xsd:string>
        <xsd:attribute name="Id" type="xsd:int>
    </xsd:complexType>

</xsd:schema>

FooClient.xsd

FooClient.xsd

<xsd:schema targetNamespace="http://www.example.com/foo"
            xmlns:core="network://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:import namespace="http://www.example.com/network"
                schemaLocation="client.xsd"/>

    <xsd:complexType name="FooClient">
        <xsd:complexContent>
            <xsd:extension base="network:Client">
                <xsd:attribute name="foo" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

</xsd:schema>

FooServer.xsd

FooServer.xsd

<xsd:schema targetNamespace="http://www.example.com/foo"
            xmlns:core="network://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:import namespace="http://www.example.com/network"
                schemaLocation="client.xsd"/>

    <xsd:complexType name="FooServer">
        <xsd:complexContent>
            <xsd:extension base="network:Server">
                <xsd:attribute name="foo" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

</xsd:schema>

FooApplication.xsd

FooApplication.xsd

<xsd:schema targetNamespace="http://www.example.com/foo"
            xmlns:core="http://www.example.com/core"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:import namespace="http://www.example.com/core"
                schemaLocation="Application.xsd"/>

    <xsd:include schemaLocation="FooClient.xsd"/>
    <xsd:include schemaLocation="FooServer.xsd"/>

    <xsd:complexType name="FooApplication">
        <xsd:complexContent>
            <xsd:extension base="core:Application">
                <xsd:sequence>
                    <xsd:element name="FooInput" type="FooClient"/>
                    <xsd:element name="FooOutput" type="FooServer"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:element name="Foo" type="FooApplication"/>

</xsd:schema>

这是一个实例文档的例子:

This is an example of an instance document:

<foo:Foo xmlns:foo="http://www.example.com/foo" 
         Id="1234"
         Name="FooInstance1">

    <FooInput Host="localhost:12345"
              Name="Input"
              foo="bar"/>

    <FooOutput Port="54321"
               Name="Output"
               foo="bar"/>

</foo:Foo>

我的目标是将 FooApplication 模式文档转换为人类可读的形式,以便负责维护应用程序的人员确切知道可用的配置选项、数据类型、默认值等.最终我将添加文档也可以添加到输出中的元素,但现在我试图保持简单.所以上面的例子可能看起来像这样:

My aim is to take the FooApplication schema document and turn it into a human readable form so that the people responsible for maintaining the application know exactly what configuration options are available, the data types, default values etc. Eventually I will add documentation elements which can also be added to the output, but for now I'm trying to keep it simple. So the example above could look something like this:

FooApplication/Id, int
FooApplication/Name, string
FooApplication/FooInput/Host, string
FooApplication/FooInput/foo, string
FooApplication/FooOutput/Port, unsignedShort
FooApplication/FooOutput/MaxConnections, int, default=32
FooApplication/FooOutput/foo, string

对于此任务,xslt 似乎是显而易见的工具.但是,我很难弄清楚如何从多个文档中提取数据.我尝试过这样的事情(例如索引 complexType 的所有元素):

For this task xslt seems like the obvious tool. However I'm having a hard time getting my head around how to pull in data from the multiple documents. I tried something like this (for example for indexing all elements of complexType):

<xsl:template match="xsd:include">
    <xsl:apply-templates select="document(@schemaLocation)"/>
</xsl:template>

<xsl:template match="xsd:import">
    <xsl:apply-templates select="document(@schemaLocation)"/>
</xsl:template>

<xsl:key name="complexType" match="xsd:complexType" use="@name"/>

然而,当使用密钥时,只有来自 FooApplicaiton.xsd 的 complexType 被解析.

However when using the key, only the complexType from FooApplicaiton.xsd is resolved.

有人对如何实现这一目标有任何见解吗?

Does anyone have any insights into how this could be achieved?

非常感谢.

推荐答案

感谢 Petru Gardea 提及我们的工具DocFlex/XML XSDDoc

Thanks, Petru Gardea, for mentioning our tool DocFlex/XML XSDDoc!

确实,使用我们的 XML 模式 doc-gen 可以将初始问题中提到的所有示例 XML 模式记录在一起.

Yes indeed, using our XML schema doc-gen it is possible to document together all those example XML schemas mentioned in the initial question.

这是我刚刚由他们生成的文档:

Here's such a doc I've just generated by them:

http://www.filigris.com/pr/stackoverflow.com/questions/8369677/using-xslt-to-transform-multiple-xml-schema-documents/xsddoc/

但我不得不说提供的 XSD 列表有些不正确.如果您从字面上理解这些文本并从中创建相应的 XSD 文件,则什么都不会起作用!(为了生成文档,我需要更正它们.)

But I have to say that the provided XSD listings are somewhat incorrect. If you take those texts literally and create corresponding XSD files from them, nothing will work! (To generate the doc I needed to correct them.)

首先,某些模式中的 XML 标记根本无效(例如在 Application.xsd 中).

First, the XML markup in some schemas is simply invalid (e.g. in Application.xsd).

其次,FooApplication.xsd 使用了不正确的类型引用.它相应地定义了元素 'FooInput' 和 'FooOutput' 的类型为 'FooClient' 和 'FooServer'.这些类型在 FooClient.xsd 和 FooServer.xsd 中定义,它们包含在 FooApplication.xsd 中.没关系.这里缺少的是这些类型是在命名空间中定义的:"http://www.example.com/foo".但是 FooApplication.xsd 中使用它们的 XML 位置绑定到不同的命名空间——默认命名空间(即没有命名空间).所以,声明:

Second, FooApplication.xsd uses incorrect type references. It defines elements 'FooInput' and 'FooOutput' with the types 'FooClient' and 'FooServer' correspondingly. Those types are defined in FooClient.xsd and FooServer.xsd, which are included in FooApplication.xsd. That's fine. What is missing here is that those types are defined in the namespace: "http://www.example.com/foo". But the XML locations in FooApplication.xsd, where they are used, are bound to a different namespace -- the default one (i.e. no namespace). So, the declaration:

<xsd:element name="FooInput" type="FooClient"/>

实际上不是指类型:

{http://www.example.com/foo}:FooClient

而是类型:

{no namespace}:FooClient

为了使类型引用正确,您需要在 中再添加一个命名空间绑定;在 FooApplication.xsd 中:

To make the type references correct, you would need to add one more namespace binding in <xsd:schema> in FooApplication.xsd:

<xsd:schema targetNamespace="http://www.example.com/foo"
        xmlns="http://www.example.com/foo"
        xmlns:core="http://www.example.com/core"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">

或使用绑定到http://www.example.com/foo".

因此,如果您曾经尝试使用我们的工具直接记录您的原始模式 DocFlex/XML XSDDoc,显然您不会收到正确的文档!

So, if you ever tried to document your original schemas straight with our tool DocFlex/XML XSDDoc, clearly you would have received no correct documentation!

(我们的 XML 模式 doc-gen 不会自动验证任何 XML 模式.它根本不能,因为,首先,这不是它的工作,其次,任何模式验证都需要额外的处理时间,这可能会让大多数人烦恼谁确定他们的架构是正确的.毕竟,你总是可以在你的构建文件中添加一些额外的架构验证步骤)

(Our XML schema doc-gen does not validate any XML schema automatically. It simply cannot, because, first, it is not its job, and second, any schema validation would take additional processing time, which may be annoying to most who are sure their schemas are correct. After all, you can always add some additional schema validation step in your build file)

最后,如果以上所说的一切都与您无关——也就是说,示例模式中的所有错误都只是这个特定问题的不准确之处——那么听听为什么会很有趣我们的工具不适合您的任务(除了任何商业、财务或组织问题).

Finally, if all said above does not concern you -- that is, all those errors in the example schemas are just inaccuracies of this particular question -- then it would be really interesting to hear why our tool does not fit to your task (besides any commercial, financial or organizational issues).

Petru Gardea 建议我们的解决方案可能会放大".但一般来说,它可能需要朝哪个方向扩大规模?听到这真是太有趣了!因为这正是我们自己关心的——如何使我们的工具文档 XML 模式更好.

Petru Gardea suggested that our solution might be "scaled up". But in what direction, in general, might it need to be scaled up? That would be really interesting to hear! Because it is precisely our own concern -- how to make our tool document XML schemas even better.

附言这个网站上还有一个问题,也和这个话题很相关:

P.S. There is one more question on this site, which is also very related to this topic:

如何将 xsd 转换为人类可读的文档?

我也提供了一个答案(尽管有些人可能认为这是一个有争议的问题,尤其是从主流观点来看).不幸的是,我当时没有这个帐户,所以我不能直接与它相关.

I provided an answer too (though some may consider it a controversial one, especially from the mainstream point of view). Unfortunately, I had no this account by then, so I cannot relate to it directly.

这篇关于使用 xslt 转换多个 xml 模式文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆