好的,想象一个场景,您想要创建一个元素
Foo
,有时包含文本,有时包含元素,例如
所以有时输出需要看起来像这样(我嵌入了一个
sortOrder
元素)
<root>
<Foo>
<sortOrder value="3" />
</Foo>
<Foo>
<sortOrder value="2" />
</Foo>
<Foo>
<sortOrder value="2" />
</Foo>
</root>
有时它需要是像这样的简单文本值
<root>
<Foo>3</Foo>
<Foo>2</Foo>
<Foo>2</Foo>
</root>
(可怕的是,我没有发明这个模式)
所以让我们补充一些意见......
<root>
<element>
<sortOrder value="3"/>
</element>
<element>
<sortOrder value="2"/>
</element>
<element>
<sortOrder value="2"/>
</element>
</root>
并编写一个模板来制作 Foo 元素
<xsl:template name="makeFoo">
<xsl:param name="value"/>
<Foo>
<xsl:copy-of select="$value"/>
</Foo>
</xsl:template>
这是第一个示例的整个 xslt,它有效!!
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="root/element">
<xsl:call-template name="makeFoo">
<xsl:with-param name="value" select="sortOrder"/>
</xsl:call-template>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template name="makeFoo">
<xsl:param name="value"/>
<Foo>
<xsl:copy-of select="$value"/>
</Foo>
</xsl:template>
</xsl:stylesheet>
让我们尝试一下第二个输出的明显效果......(使用相同的“库函数 makeFoo”)
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="root/element">
<xsl:call-template name="makeFoo">
<xsl:with-param name="value" select="sortOrder/@value"/>
</xsl:call-template>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template name="makeFoo">
<xsl:param name="value"/>
<Foo>
<xsl:copy-of select="$value"/>
</Foo>
</xsl:template>
</xsl:stylesheet>
啊...几乎...这就是这样..
它复制了属性...聪明...但不是我想要的。
<root>
<Foo value="3" />
<Foo value="2" />
<Foo value="2" />
</root>
那么我怎样才能得到我想要的......
我尝试过...
<xsl:with-param name="value" select="sortOrder/@value/text()"/>
不(毫不奇怪,那里没有文本节点)
这个..
<xsl:with-param name="value">
<xsl:value-of select="sortOrder/@value"/>
</xsl:with-param>
有效!!!
大概我们正在强制 xsl 生成一个传递然后复制的文本节点。
但是有没有办法在选择中做到这一点?即在 XPath 表达式中?
属性没有子文本节点。要获取属性的 string-value,您应该使用
xsl:value-of
指令。如果您必须使用 xsl:copy
(为什么?),您首先需要将属性转换为字符串。在你的例子中,这(可能)意味着:
<xsl:with-param name="value" select="string(sortOrder/@value)"/>
我希望这能回答你的问题,我觉得这个问题很令人困惑。