Match an element with a dynamic attribute value

后端 未结 1 1870
名媛妹妹
名媛妹妹 2020-12-12 03:19

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

相关标签:
1条回答
  • 2020-12-12 03:29

    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>&lt;?php </xsl:text>
        <xsl:apply-templates select="xsd:schema"/>
    </xsl:template>
    

    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>
    

    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>
    

    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 */
    }
    
    0 讨论(0)
提交回复
热议问题