我有许多xml架构文档,用于描述我的应用程序的配置设置。 xml架构沿着以下几行显示:
Client.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>
Server.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。
有没有人对如何实现这一目标有任何见解?
非常感谢提前。
答案 0 :(得分:0)
除了更好地编写模式之外,您不需要以任何方式处理模式。
尽可能在允许xs:annotation
的任何地方使用xs:documentation
元素及其子xs:annotation
。
然后,您可以使用良好的XML编辑器(如Visual Studio XML编辑器)和IDE的智能感知器自动创建架构实例:
XML编辑器还会使用红色波形标记任何错误,并且“错误”窗口会在用户输入XML文档时实时显示任何错误或警告消息。
最后:如果在创建注释之后仍然希望生成类似于单独(甚至打印)文档的内容,则可以使用XSLT轻松处理模式,并输出可用的注释。
答案 1 :(得分:0)
首先看一下DocFlex,看看他们对XML Schema文档的处理方法是否合理。然后,您应该可以向上或向下扩展。对于任何微不足道的事情,如果您必须构建自己的doc系统,我认为它应该基于XML Schema Object Model API(XSOM),然后创建XML然后可以使用XSLT ... < / p>
答案 2 :(得分:0)
xsl:key不适合您的原因是它只在单个文档中搜索。解决方案可能是创建一个复合文档(在xsl:variable中),它合并不同模式文档的内容,然后在其上使用xsl:key。
(或者使用Saxon-EE,它将根据需要自动创建索引,避免使用显式键。)
通常,使用XSLT操作原始模式文档很困难,因为在XSD中编写相同内容的方法有很多种。但是,如果您可以控制架构文档中使用的编码样式,则很有可能实现。
答案 3 :(得分:0)
谢谢,Petru Gardea,提及我们的工具 的 DocFlex/XML XSDDoc 强>!
是的,使用我们的XML模式doc-gen,可以将初始问题中提到的所有示例XML模式一起记录。
以下是我刚刚由他们制作的文档:
但我不得不说提供的XSD列表有点不正确。如果你从字面上理解这些文本并从中创建相应的XSD文件,那么什么都行不通! (要生成我需要更正它们的文档。)
首先,某些模式中的XML标记无效(例如在Application.xsd中)。
其次,FooApplication.xsd使用了错误的类型引用。 它相应地使用类型'FooClient'和'FooServer'定义元素'FooInput'和'FooOutput'。 这些类型在FooClient.xsd和FooServer.xsd中定义,它们包含在FooApplication.xsd中。没关系。 这里缺少的是那些类型在命名空间中定义:“http://www.example.com/foo”。但是FooApplication.xsd中使用它们的XML位置绑定到不同的命名空间 - 默认命名空间(即没有命名空间)。声明:
<xsd:element name="FooInput" type="FooClient"/>
referes实际上不属于这种类型:
{http://www.example.com/foo}:FooClient
而是类型:
{no namespace}:FooClient
要使类型引用正确,您需要在&lt; xsd:schema&gt;中添加一个名称空间绑定。在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 直接记录原始模式,那么显然您没有收到正确的文档!
(我们的XML模式doc-gen不会自动验证任何XML模式。它根本不能,因为,首先,它不是它的工作,其次,任何模式验证都需要额外的处理时间,这对大多数人来说可能很烦人谁确定他们的模式是正确的。毕竟,你总是可以在你的构建文件中添加一些额外的模式验证步骤)
最后,如果上述所有内容都与您无关 - 也就是说,示例模式中的所有错误都只是这个特定问题的不准确之处 - 那么听听为什么会非常有趣我们的工具不适合您的任务(除了任何商业,财务或组织问题)。
Petru Gardea建议我们的解决方案可能会“扩大规模”。但总的来说,它可能需要扩大规模吗?听到这真的很有意思!因为这正是我们自己关注的问题 - 如何使我们的工具文档XML模式更好。
<强> P.S。强> 此网站还有一个问题,与此主题非常相关:
How to convert xsd to human readable documentation?
我也提供了answer(虽然有些人认为这是一个有争议的,特别是从主流的角度来看)。不幸的是,到那时我没有这个帐户,所以我无法直接与它联系。