I\'m trying to prototype a transform to turn xsl:schema
into a php interface. I\'m having a little trouble matching xsd:simpleType
elements that ha
The simpleType
node is never selected because in the template where you match xsd:schema
, you only apply the templates to the xsd:element
child subtree. The xsd:simpleType
sibling will never be processed.
If you want to allow the processing of all children of a node, you should include an empty <xsl:apply-templates/>
inside the xsd:schema
template.
That still won't generate the result you want. It's actually much simpler. To generate the code fragment you expect, you don't need to read the xsd:simpleType
element, since the attribute that contains the type you want can be directly obtained from the @type
attribute of xsd:element
using xsd:value-of
, and you can just print the $a
immediately after it:
XmlString(<xsl:value-of select="@type"/> $a)
Since you are generating text, you should use the <xsl:text>
elements to control how your whitespace will be distributed. For instance, if you use:
<xsl:template match="/">
<xsl:text><?php </xsl:text>
<xsl:apply-templates select="xsd:schema"/>
</xsl:template>
You won't need to worry about always placing the <?php
text immediately after the <xsl:template>
and can indent your code normally. You can also include newlines with the 

character (and it won't break your formatting):
<xsl:template match="xsd:schema">
<xsl:text>interface FromXsd {
</xsl:text>
<xsl:apply-templates select="xsd:element"/><xsl:text>
</xsl:text>
<xsl:apply-templates select="xsd:annotation"/>
<xsl:text>
}</xsl:text>
</xsl:template>
I edited your XSL and made these changes in the XSL document below:
<xsl:stylesheet version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="*"/>
<xsl:template match="/">
<xsl:text><?php </xsl:text>
<xsl:apply-templates select="xsd:schema"/>
</xsl:template>
<xsl:template match="xsd:schema">
<xsl:text>interface FromXsd {
</xsl:text>
<xsl:apply-templates select="xsd:element"/><xsl:text>
</xsl:text>
<xsl:apply-templates select="xsd:annotation"/>
<xsl:text>
}</xsl:text>
</xsl:template>
<xsl:template match="xsd:element">
<xsl:apply-templates select="xsd:annotation"/>
<xsl:text> abstract public function build</xsl:text>
<xsl:value-of select="normalize-space(@name)"/>
<xsl:text>XmlString(</xsl:text>
<xsl:value-of select="@type"/><xsl:text> $a</xsl:text>
<xsl:text>);</xsl:text>
</xsl:template>
<xsl:template match="xsd:annotation">
<xsl:text> /* </xsl:text>
<xsl:value-of select="normalize-space(.)"/>
<xsl:text> */</xsl:text>
</xsl:template>
</xsl:stylesheet>
If you have an input such as:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Foo" type="Bar"/>
<xsd:simpleType name="Bar">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="32"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:annotation>
<xsd:documentation>This is a comment</xsd:documentation>
</xsd:annotation>
</xsd:schema>
It will produce the result below:
<?php interface FromXsd {
abstract public function buildFooXmlString(Bar $a);
/* This is a comment */
}