4

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:

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>

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>

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

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"/>

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

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

Many thanks in advance.

moagstar
  • 41
  • 1
  • 1
  • 4

4 Answers4

0

You don't need to process the schemas in any way, except for writing the schemas better.

Use the xs:annotation element and its child xs:documentation as much as possible in any place where xs:annotation is allowed.

Then you can create instances of your schema(s) using a good XML editor such as the Visual Studio XML Editor and the IDE's intellisense automatically:

  • Displays the annotations (that describe the meaning and type).
  • Prompts/enumerates the possible names and values for attriburtes and the possible children of an element. For all of these when selected (before pressing Enter) their respective annotation is also displayed by the intellisense.

The XML Editor also marks with red squiggles any errors and the Errors window displays any error or warning messages -- al of this in real time while the user is entering the XML document.

Finally: If after creating the annotations you still want to produce something like a separate (or even printed) documentation, you can easily process the schemas with XSLT and just output the available annotations.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
0

I would start by taking a look at DocFlex and see if their approach to XML Schema documentation makes sense to you. You should then be able to scale up or down. For anything but trivial, if you would have to build your own doc system, I would think that it should be based on an XML Schema Object Model API (XSOM), with that creating XML that could then be presented using XSLT...

Petru Gardea
  • 21,373
  • 2
  • 50
  • 62
0

The reason that xsl:key isn't working for you is that it only searches within a single document. The solution might be to create a composite document (in an xsl:variable) that merges the contents of the different schema documents, and then use xsl:key on that.

(Or use Saxon-EE which will create indexes automatically where needed, avoiding the need for explicit keys.)

Generally, manipulating raw schema documents using XSLT is difficult because there are so many different ways of writing the same thing in XSD. However, if you have control over the coding style used in the schema documents, it is quite possible to achieve.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Thanks, I ended up making a composite document in the end, but in seperate xslt passes, works like a charm. I couldn't get it working in a single pass, the xslt processor didn't recognise the xsl:variable as a node set. Although it's easier doing it in seperate steps and it keeps my stylesheets simple, it does somehow feel like cheating. – moagstar Dec 04 '11 at 21:36
0

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

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/

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.)

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

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"/>

referes actually not to the type:

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

but rather to the type:

{no namespace}:FooClient

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">

or use an additional namespace prefix bound to "http://www.example.com/foo".

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!

(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 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:

How to convert xsd to human readable documentation?

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.

Community
  • 1
  • 1
Leonid Rudy
  • 255
  • 4
  • 5
  • Thanks for your feedback. The DocFlex tool looks very interesting, however I am looking to convert to simple format which can be used in our internal wiki. The idea is that the people responsible for maintaining the application have a list of configuration options available, with comments, default values etc. In short the output from DoxFlex is too complicated. It is not so much the schema I want to document, but the configuration options. I am just specifying which configuration options I expected in xsd so that I can valid config files, and auto generate this wiki documentation. – moagstar Dec 07 '11 at 15:12
  • p.s. The problems with these schemas come from the fact that I'd written them here from memory, the actual xsd files don't contain these errors. – moagstar Dec 07 '11 at 15:22
  • OK. What you need is also possible to do with our tool! The XML schema doc-generator, which we call "DocFlex/XML XSDDoc", is in fact just a template set. The whole software is DocFlex/XML (see http://www.filigris.com/products/docflex_xml/). It is a system that in many ways works the same as XSLT. Templates are equivalent of XSLT scripts. The DocFlex/XML Generator, which is a freeware part of both DocFlex/XML editions, plays the role of XSLT processor. What we have above is the Template Designer that provides a GUI to create/edit templates. – Leonid Rudy Dec 08 '11 at 07:50
  • It represents the template code in a more interactive visual way that tries to imitate the generated output whenever possible. Our template language is not based on XSLT (though some ideas were borrowed). It is completely our proprietary technology. This allows us to quickly introduce new features whenever needed or invented. That, I believe, let us make this system a lot more powerful than XSLT (it is in development already since 2002 and its focus is not only XML, but far beyond). On the negative, of course, this is not any kind of open standard coming from some venerable consortium. – Leonid Rudy Dec 08 '11 at 07:53
  • Rather, it is currently provided, supported and explained only by us. But it allows us to do certain things that nobody does, which is why we are able to survive. Our customers, however few of them yet, already include people sitting in such places like Adobe, IBM and Microsoft, which, I believe, would hate to deal with such little guys, if only they could find what they need elsewhere. – Leonid Rudy Dec 08 '11 at 07:55
  • I think, using DocFlex/XML SDK (that covers TD), it is possible to program templates that would retrieve from XML schemas any info you want and represent it as any output you need. Currently, we generate directly three formats: HTML, RTF and TXT (plain text). The plain text output, effectively, allows you to specify templates so as to generate any kind of XML markup you want (that functionality is a direct replacement of XSLT). I know, one our customer even managed to generate some DITA output with this.But of course, DocFlex/XML SDK is not free. (Otherwise, we could not sustain our business.) – Leonid Rudy Dec 08 '11 at 07:58
  • I could offer you the following. You could purchase a license for DocFlex/XML SDK. That license includes 1 year free support. As your task is likely far less complicated than what we have already done (i.e. XSDDoc), we could adapt XSDDoc templates to do what you need. I think that would take no much time from us. So, it would be considered as a part of the support, that is free. We will provide you the new templates with all explanations how they work, so you and your colleagues could maintain/modify them further. – Leonid Rudy Dec 08 '11 at 08:00
  • If you like such an idea, please write me to discuss this further. The contact e-mail you can find on our web-site: http://www.filigris.com or http://www.docflex.com (the same). Best regards, Leonid Rudy – Leonid Rudy Dec 08 '11 at 08:01