将元素与动态属性值匹配 [英] Match an element with a dynamic attribute value

查看:76
本文介绍了将元素与动态属性值匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个转换原型,以将xsl:schema转换为php接口.我在匹配xsd:simpleType元素时遇到了一些麻烦,这些元素的name属性与xsd:element元素的type属性匹配.假设我有一个这样的模式:

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

Here's the xslt I have so far:

<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="/">&lt;?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();
}

如何选择具有与elementtype匹配的name属性的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模板中包含一个空的<xsl:apply-templates/>.

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元素,因为可以使用xsd:value-ofxsd:element@type属性直接获取包含所需类型的属性,并且您可以在$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>&lt;?php </xsl:text>
    <xsl:apply-templates select="xsd:schema"/>
</xsl:template>

您不必担心总是将&lt;?php文本紧接在<xsl:template>之后,并且可以正常缩进代码.您还可以使用&#xa;字符添加换行符(这样不会破坏您的格式):

You won't need to worry about always placing the &lt;?php text immediately after the <xsl:template> and can indent your code normally. You can also include newlines with the &#xa; character (and it won't break your formatting):

<xsl:template match="xsd:schema">
    <xsl:text>interface FromXsd {&#xa;</xsl:text>
    <xsl:apply-templates select="xsd:element"/><xsl:text>&#xa;</xsl:text>
    <xsl:apply-templates select="xsd:annotation"/>
    <xsl:text>&#xa;}</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.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>&lt;?php </xsl:text>
        <xsl:apply-templates select="xsd:schema"/>
    </xsl:template>

    <xsl:template match="xsd:schema">
        <xsl:text>interface FromXsd {&#xa;</xsl:text>
        <xsl:apply-templates select="xsd:element"/><xsl:text>&#xa;</xsl:text>
        <xsl:apply-templates select="xsd:annotation"/>
        <xsl:text>&#xa;}</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 */
}

这篇关于将元素与动态属性值匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆