开发者

Nothing returned for element name (XSL/XPath)

I have code that I expect to return the element name, but nothing is returned.

The following code is from an XSL doc that generates another XSL 开发者_运维知识库doc.. where $expression is a variable that dynamically created an XPath expression.

<xsl:template match="/">
    ...
    <xslt:template match="{$expression}">
        <elem key="{name()}">
            <xslt:copy-of select="@*"/>
            <xslt:for-each select="@*">
                <xslt:sort select="name()"/>
                <attribute>|<xslt:value-of select="name()"/>|</attribute>
            </xslt:for-each>
        </elem>
    </xslt:template>
    ...
</xsl:template>

That code then generates the second XSL doc with this code.. notice how @key is blank.

<xsl:template match="//*[@name='Spot']">
    <elem key="">
        <xsl:copy-of select="@*" />
        <xsl:for-each select="@*">
            <xsl:sort select="name()" />
            <attribute>|<xsl:value-of select="name()" />|</attribute>
        </xsl:for-each>
    </elem>
</xsl:template>

Besides the @key being blank, everything works as expected. My only problem is displaying the name of the element.

EDIT: To clarify what I'm actually looking for, I need the names of the elements from the results returned by <xslt:template match="{$expression}">.

Thanks! :)


Because your transformation is producing itself XSLT code and you want to have in the result:

<elem key="{name()}">

you must escape the { and }, so that the AVT is not evaluated immediately.

Producing { and } as-is is done by doubling them as specified in the XSLT spec:

"When an attribute value template is instantiated, a double left or right curly brace outside an expression will be replaced by a single curly brace. "

Therefore, replace:

<xslt:template match="{$expression}">   
    <elem key="{name()}">   
        <xslt:copy-of select="@*"/>   
        <xslt:for-each select="@*">   
            <xslt:sort select="name()"/>   
            <attribute>|<xslt:value-of select="name()"/>|</attribute>   
        </xslt:for-each>   
    </elem>   
</xslt:template> 

with:

<xslt:template match="{$expression}">   
    <elem key="{{name()}}">   
        <xslt:copy-of select="@*"/>   
        <xslt:for-each select="@*">   
            <xslt:sort select="name()"/>   
            <attribute>|<xslt:value-of select="name()"/>|</attribute>   
        </xslt:for-each>   
    </elem>   
</xslt:template> 

and as result you will get:

<xsl:template match="//*[@name='Spot']">       
    <elem key="{name()}">       
        <xsl:copy-of select="@*" />       
        <xsl:for-each select="@*">       
            <xsl:sort select="name()" />       
            <attribute>|<xsl:value-of select="name()" />|</attribute>       
        </xsl:for-each>       
    </elem>       
</xsl:template> 

Note: I am surprised that this code works at all. You should be using the <xsl:namespace-alias> XSLT instruction.


/ returns the node that contains the root node of the XML document, not the root node itself. This node does not have a name.

You want the name of the child of that node, I'm guessing. You can do it a number of ways. One is you can change your <xsl:template match="/"> to <xsl:template match="/root"> (where root is whatever the root node's name is) or you can change <elem key="{name()}"> to <elem key="{name(root)}">.

But you might not know the name in advance. If that's the case you can go with <xsl:template match="/*">. That will return all children of the root's parent. In this case there is always only one root. Then you can use <elem key="{name()}"> normally.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜