我想编写一个匹配属性而不是节点的XSL模板,
我认为有这样的事情:
<xsl:template match="@href | @conref | @conrefend">
<xsl:message select="."/>
</xsl:template>
将匹配这3个属性名称中的任何一个并打印以控制属性的值,因为范围是属性本身而不是节点。
但我的测试证明我错了,我只能匹配包含以下任何属性的节点:
<xsl:template match="*[@href or @conref or @conrefend]">
<xsl:message select="if(not(@href))
then
if(not(@conref))
then @conrefend
else @conref
else @href"/>
</xsl:template>
这种方法的问题在于,如果碰巧存在一个具有多个属性的节点,那么只有一个被处理,我需要全部处理它们。
为什么第一种方法不起作用的任何想法?
EDIT1: 完整的xslt:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@conref|@conrefend|@href">
<xsl:message select="."/>
</xsl:template>
</xsl:stylesheet>
测试XML:
<links>
<image conref="COPY-GUID/*+-862416}39-37CD-4CF7-A7AA-F09F4A763944" />
</links>
现在XSLT没有匹配任何内容。
答案 0 :(得分:1)
您确实可以像第一个模板那样匹配模板中的属性。别的一定是错的......
看一下身份变换:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
它可以很好地匹配您正在进行的替代方案,其中一个替代方案适用于所有属性(@*
)。
现在考虑xsl:apply-templates
语句。请注意如何显式调出@*
。您确定要为模板提供应用属性的机会吗?如果你打电话,xsl:apply-templates
就是这样,例如:
<xsl:apply-templates select="*"/>
意识到只会选择元素,而不是属性。另请注意,node()
也不包含属性。
右。您的属性匹配模板永远不会有机会申请。
添加上面的身份模板,或类似的内容:
<xsl:template match="/">
<xsl:apply-templates select="//@*"/>
</xsl:template>
为您的属性匹配模板提供申请机会。
答案 1 :(得分:1)
默认情况下,XSLT不会查找与属性节点匹配的模板。将模板明确应用于输入XML中的所有属性。
顺便问一下,您确定要使用xsl:message
吗? xsl:message
的内容不包含在转换输出中。你的意思是xsl:value-of
?此外,如果输出文本,则应将输出方法声明为文本。
<强>样式表强>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//@*"/>
</xsl:template>
<xsl:template match="@conref">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
文字输出
COPY-GUID/*+-862416}39-37CD-4CF7-A7AA-F09F4A763944
实际上,在这个非常简单的情况下,第一个模板就足以获得相同的输出:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//@*"/>
</xsl:template>
</xsl:stylesheet>
这是因为,一旦模板应用于属性节点,就会有一个内置模板默认输出其字符串值。
答案 2 :(得分:1)
您当前的方法存在的问题是,从不应用与属性匹配的模板。它没有被应用,因为内置模板规则仅匹配根节点和元素节点,并且它仅将模板应用于子节点节点。要将模板应用于属性,您必须自己明确地应用它。