这不是一个问题,而是一个令人惊讶的xslt2体验,我想分享。
拿片段(从另一个中减去一组)
<xsl:variable name="v" as="node()*">
<e a="a"/>
<e a="b"/>
<e a="c"/>
<e a="d"/>
</xsl:variable>
<xsl:message select="$v/@a[not(.=('b','c'))]"/>
<ee>
<xsl:sequence select="$v/@a[not(.=('b','c'))]"/>
</ee>
我应该得到什么?我期待在控制台和
<ee>a d</ee>
在输出。
我得到的是
<?attribute name="a" value="a"?><?attribute name="a" value="d"?>
在控制台和
<ee a="d"/>
在输出。我应该知道将$ v / @ a作为一系列属性节点来预测输出。
为了得到我想要的东西,我不得不将属性序列转换为字符串序列,如:
<xsl:variable name="w" select="$v/@a[not(.=('b','c'))]" as="xs:string*"/>
问题: 是否使用了属性序列(或者它只是节点集概念的有趣效果)? 如果是这样,我能否静态输入一系列属性,比如我能输入一系列字符串:('a','b','c','d') 是否有任何内联语法将属性序列转换为字符串序列? (为了达到省略变量w的相同结果) 它似乎是一种使用xsl:sequence创建属性的优雅方式。或者这是滥用xslt2,不是标准所涵盖的?
至于“是否有任何内联语法将属性序列转换为字符串序列”,您只需添加一个步骤$v/@a[not(.=('b','c'))]/string()
。或者使用for $a in $v/@a[not(.=('b','c'))] return string($a)
,当然还有XPath 3 $v/@a[not(.=('b','c'))]!string()
。
我不确定关于“使用属性序列”的问题是什么,特别是因为它提到了节点集的XPath 1概念。如果你想编写一个函数或模板来从输入返回一些原始属性节点,那么xsl:sequence
允许这样做。当然,在像元素内容这样的序列构造函数中,如果你在https://www.w3.org/TR/xslt20/#constructing-complex-content中查看10),最后会创建一个属性的副本。
至于创建一系列属性,你不能在无法创建新节点的XPath中这样做,你可以在XSLT中这样做:
<xsl:variable name="att-sequence" as="attribute()*">
<xsl:attribute name="a" select="1"/>
<xsl:attribute name="b" select="2"/>
<xsl:attribute name="c" select="3"/>
</xsl:variable>
然后你可以在其他地方使用它,就像在
<xsl:template match="/*">
<xsl:copy>
<element>
<xsl:sequence select="$att-sequence"/>
</element>
<element>
<xsl:value-of select="$att-sequence"/>
</element>
</xsl:copy>
</xsl:template>
并会得到
<example>
<element a="1" b="2" c="3"/>
<element>1 2 3</element>
</example>
http://xsltfiddle.liberty-development.net/jyyiVhg
XQuery具有更紧凑的语法,而XPath允许表达式创建新节点:
let $att-sequence as attribute()* := (attribute a {1}, attribute b {2}, attribute c {3})
return
<example>
<element>{$att-sequence}</element>
<element>{data($att-sequence)}</element>
</example>