问题描述
我正在尝试原型转换以将 xsl:schema 转换为 php 界面.我在匹配 xsd:simpleType 元素时遇到了一些麻烦,这些元素的 name 属性与 xsd:element<的 type 属性匹配/code> 元素.假设我有一个这样的架构:
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 have a name attribute matching the type attribute of xsd:element elements. Suppose I have a schema like this:
<xsd:schema xmlns:xsd="http://www.51sjk.com/Upload/Articles/1/0/335/335696_20221101163042064.jpg"> <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:
Here's the xslt I have so far:
<xsl:stylesheet version="1.0" xmlns:xsd="http://www.51sjk.com/Upload/Articles/1/0/335/335696_20221101163042064.jpg" xmlns:xsl="http://www.51sjk.com/Upload/Articles/1/0/335/335696_20221101163042971.jpg"> <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>
它产生大部分所需的结果,但不包括括号内的任何内容:
It produces most of the desired result, but doesn't include anything inside the parentheses:
<?php interface Foo { public abstract function buildFooXmlString(); }
如何选择name 属性与元素 的type 匹配的simpleType 节点?(名称对于 xsd 类型必须是唯一的.)
How can I select the simpleType node with the name attribute matching the type of the element? (Names have to be unique for xsd types.)
推荐答案
simpleType 节点永远不会被选中,因为在您匹配 xsd:schema 的模板中,您只需要将模板应用于 xsd:element 子树.xsd:simpleType 兄弟永远不会被处理.
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.
如果你想允许处理一个节点的所有子节点,你应该在 xsd:schema 中包含一个空的
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.
那仍然不会产生你想要的结果.它实际上要简单得多.要生成您期望的代码片段,您不需要读取 xsd:simpleType 元素,因为包含您想要的类型的属性可以直接从 @type使用 xsd:value-of 的 xsd:element 的 code> 属性,您可以在它之后立即打印 $a :
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)
由于您正在生成文本,因此您应该使用 <xsl:text> 元素来控制您的空白的分布方式.例如,如果您使用:
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>
您无需担心总是将 <?php 文本紧跟在 <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>
我编辑了您的 XSL 并在下面的 XSL 文档中进行了这些更改:
I edited your XSL and made these changes in the XSL document below:
<xsl:stylesheet version="1.0" xmlns:xsd="http://www.51sjk.com/Upload/Articles/1/0/335/335696_20221101163042064.jpg" xmlns:xsl="http://www.51sjk.com/Upload/Articles/1/0/335/335696_20221101163042971.jpg"> <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.51sjk.com/Upload/Articles/1/0/335/335696_20221101163042064.jpg"> <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 */ }