我正在尝试将变换原型化为将xsl:schema
转换为php界面。我在匹配xsd:simpleType
个name
属性匹配type
元素xsd:element
属性的元素时遇到了一些麻烦。假设我有这样的架构:
<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:schema>
我想得到以下结果。
<?php
interface Foo {
public abstract function buildFooXmlString(Bar $a);
}
这是我到目前为止的xslt:
<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="/"><?php <xsl:apply-templates select="xsd:schema"/></xsl:template>
<xsl:template match="xsd:schema">interface FromXsd { <xsl:apply-templates select="xsd:element"/> }</xsl:template>
<xsl:template match="xsd:element">
<xsl:apply-templates select="xsd:annotation"/>
abstract public function build<xsl:value-of select="normalize-space(@name)"/>XmlString(<xsl:apply-templates select="@type"/>);
</xsl:template>
<xsl:template match="xsd:annotation">/* <xsl:value-of select="normalize-space()"/> */</xsl:template>
<xsl:template match="@type"><xsl:apply-templates select="//xsd:simpleType[@name=normalize-space()]"/></xsl:template>
<xsl:template match="xsd:simpleType"><xsl:value-of select="local-name()"/> $a</xsl:template>
</xsl:stylesheet>
它产生了大部分所需的结果,但在括号内没有包含任何内容:
<?php
interface Foo {
public abstract function buildFooXmlString();
}
如何选择simpleType
属性与name
的{{1}}匹配的type
节点? (对于xsd类型,名称必须是唯一的。)
答案 0 :(得分:4)
从不选择simpleType
节点,因为在匹配xsd:schema
的模板中,您只将模板应用于xsd:element
子树。永远不会处理xsd:simpleType
兄弟。
如果您想允许处理节点的所有子节点,则应在<xsl:apply-templates/>
模板中包含空xsd:schema
。
仍然无法生成您想要的结果。它实际上要简单得多。要生成您期望的代码片段,您不需要阅读xsd:simpleType
元素,因为包含所需类型的属性可以直接从@type
xsd:element
属性获取使用xsd:value-of
,您可以在其后立即打印$a
:
XmlString(<xsl:value-of select="@type"/> $a)
由于您要生成文本,因此应使用<xsl:text>
元素来控制如何分配空白。例如,如果您使用:
<xsl:template match="/">
<xsl:text><?php </xsl:text>
<xsl:apply-templates select="xsd:schema"/>
</xsl:template>
您不必担心始终在<?php
之后立即放置<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并在下面的XSL文档中进行了这些更改:
<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>
如果您输入的内容如下:
<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>
它将产生以下结果:
<?php interface FromXsd {
abstract public function buildFooXmlString(Bar $a);
/* This is a comment */
}