Using xslt to convert multiple XML schema documents

I have several xml schema documents that are used to describe configuration options for my application. The xml schemas look something like this:

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 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 goal is to take the FooApplication schema document and turn it into a readable form so that the people responsible for maintaining the application know exactly what configuration options are available, data types, default values, etc. In the end, I will add documentation of elements that can also be added to the output, but at the moment I'm trying to make it simple. So the example above might 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 an obvious tool. However, I hardly raise my head on how to extract data from several documents. I tried something like this (e.g. to index all complexType elements):

 <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 complexType from FooApplicaiton.xsd is allowed.

Does anyone have an idea of โ€‹โ€‹how this can be achieved?

Thank you very much in advance.

+4
source share
4 answers

You do not need to process the schemes in any way, except how best to write the schemes.

Use the xs:annotation element and its child xs:documentation as much as possible anywhere xs:annotation allowed .

You can then automatically instantiate your schema using a good XML editor, such as the Visual Studio XML editor and the intellisense IDE:

  • Displays annotations (describing the meaning and type).
  • Requests / lists possible names and values โ€‹โ€‹of attributes and possible child elements. For all of them, when you select (before pressing Enter), their corresponding annotation is also displayed in intellisense.

The XML editor also notes that the red tablets are some kind of errors, and any errors or warnings are displayed in the Errors window, including in real time, when the user enters an XML document.

Finally . If after creating annotations you still want to create something like separate (or even printed) documentation, you can easily process the diagrams using XSLT and simply display the available annotations.

0
source

I would start by looking at DocFlex and seeing if their approach to XML Schema documentation makes sense. Then you can scale up or down. Whatever, but trivial, if you need to create your own document system, I would think that it should be based on an Object Model API (XSOM) XML object that creates XML, which can then be represented using XSLT ...

0
source

The reason xsl: key does not work for you is because it only searches in one document. The solution may be to create a compound document (in the xsl :) variable, which combines the contents of different schema documents, and then uses xsl: key.

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

Manipulating raw schema documents using XSLT is usually difficult because there are so many different ways to write the same thing in XSD. However, if you have control over the coding style used in the schema documents, it can be achieved.

0
source

Thanks to Petra Gardea for mentioning our DocFlex / XML XSDDoc tool !

Yes, indeed, using our doc-gen XML Schema, you can combine all of these examples of XML Schemas mentioned in the original question.

Here is a document that I 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 lists are somewhat incorrect. If you take these texts literally and create the corresponding XSD files from them, nothing will work! (To create a document, I needed to fix them.)

First, the XML markup in some schemas is simply incorrect (for example, in Application.xsd).

Secondly, FooApplication.xsd uses incorrect type references. It defines the elements "FooInput" and "FooOutput" with types "FooClient" and "FooServer" respectively. These types are defined in FooClient.xsd and FooServer.xsd, which are included in FooApplication.xsd. It's great. What is missing here is that these types are defined in the namespace: " http://www.example.com/foo ". But the XML locations in FooApplication.xsd, where they are used, are associated with a different namespace - by default (i.e. No namespace). So, the declaration:

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

not actually referring to type:

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

but rather to the type:

 {no namespace}:FooClient 

For proper type references, you need to add another 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 the optional namespace prefix associated with http://www.example.com/foo . "

So, if you ever tried to document your source schemas directly with our DocFlex / XML XSDDoc tool , it is clear that you would not get the right documentation!

(Our XML doc-gen schema does not automatically validate any XML schema. It simply cannot, because firstly, this is not its work, and secondly, any validation of the schema will require additional processing time, which can annoy most sure that their schemas are correct. In the end, you can always add an extra step to verify the schema in your build file)

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

Petru Gardea suggested that our decision could be "increased." But in what direction, in general, perhaps it will need to be increased? That would be really interesting to hear! Because it is our own concern - how to make our tool to document XML schemas even better.

PS There is another question on this site that is also very related to this topic:

How to convert xsd to human readable documentation?

I provided an answer (although some of them may consider it controversial, especially from the point of view of the main one). Unfortunately, by that time I did not have this account, so I can not directly relate to it.

0
source

Source: https://habr.com/ru/post/1384489/


All Articles