【发布时间】:2012-01-12 06:29:21
【问题描述】:
我有许多 xml 架构文档,用于描述我的应用程序的配置设置。 xml 模式看起来类似于以下几行:
客户端.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>
Application.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
<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
<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
<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>
这是一个实例文档的示例:
<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 架构文档并将其转换为人类可读的形式,以便负责维护应用程序的人员准确了解可用的配置选项、数据类型、默认值等。最终我将添加文档也可以添加到输出中的元素,但现在我试图保持简单。所以上面的例子可能看起来像这样:
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 的所有元素):
<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 被解析。
有人对如何实现这一点有任何见解吗?
非常感谢。
【问题讨论】: