Xslt 按输出的特定顺序对属性排序
如何在不显式写入元素属性的情况下按特定顺序写入元素属性 考虑:Xslt 按输出的特定顺序对属性排序,xslt,attributes,Xslt,Attributes,如何在不显式写入元素属性的情况下按特定顺序写入元素属性 考虑: <xsl:template match="Element/@1|@2|@3|@4"> <xsl:if test="string(.)"> <span> <xsl:value-of select="."/><br/> </span> </xsl:if> </xsl:templ
<xsl:template match="Element/@1|@2|@3|@4">
<xsl:if test="string(.)">
<span>
<xsl:value-of select="."/><br/>
</span>
</xsl:if>
</xsl:template>
理想情况下,我不想测试每个属性是否有值。我想知道我是否可以设定我的展示顺序?或者我需要显式地执行此操作并重复if测试,如中所示:
<xsl:template match="Element">
<xsl:if test="string(./@1)>
<span>
<xsl:value-of select="./@1"/><br/>
</span>
</xsl:if>
...
<xsl:if test="string(./@4)>
<span>
<xsl:value-of select="./@4"/><br/>
</span>
</xsl:if>
</xsl:template>
在这种情况下可以做什么?我会对属性的本地名称使用xsl:sort来获得您想要的结果。我也会使用不同的模式,这样结果就不会在其他地方意外调用
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Element">
<xsl:apply-templates select="@*" mode="sorted">
<xsl:sort select="local-name()" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Element/@a|@b|@c|@d" mode="sorted">
<xsl:if test="string(.)">
<span>
<xsl:value-of select="."/><br/>
</span>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
不生成依赖于属性顺序的XML。这是非常脆弱的,至少我会认为它是坏的风格。XML不是这样设计的<代码>和
是明确等效的
如果您想要有序输出,请对输出进行排序(而不是依赖有序输入)
此外,match=“Element/@1 |@2 |@3 |@4”
并不等同于match=“Element/@1 | Element/@2 | Element/@3 | Element/@4”
,但我相信你指的是后者
也就是说,你可以做到:
<xsl:template match="Element/@1|Element/@2|Element/@3|Element/@4">
<xsl:if test="string(.)">
<span>
<xsl:value-of select="."/><br/>
</span>
</xsl:if>
</xsl:template>
<xsl:template match="Element">
<xsl:apply-templates select="@1|@2|@3|@4">
<!-- order your output... -->
<xsl:sort select="name()" />
</xsl:apply-templates>
</xsl:template>
编辑:我认为
@1
等只是示例,因为在XML中名称实际上不能以数字开头。在前面的问题中,您似乎使用XSLT 2.0,所以我希望这一次也可以使用XSLT 2.0解决方案
顺序不是在模板的匹配模式中确定的,而是在执行xsl:apply-templates时确定的。因此(使用XSLT2.0),您可以简单地按照所需的顺序编写属性序列,例如,
将按照该顺序处理属性
XSLT1.0没有序列,只有节点集。要产生相同的结果,请按要求的顺序使用xsl:apply templates
,例如:
<xsl:apply-templates select="@att2"/>
<xsl:apply-templates select="@att1"/>
<xsl:apply-templates select="@att3"/>
线索是马丁·霍宁的答案 复制属性并有条件地将新属性添加到属性列表的末尾 将rel=“noopener noreferrer”添加到所有外部链接
<xsl:template match="a">
<xsl:copy>
<xsl:if test="starts-with(./@href,'http')">
<xsl:apply-templates select="./@*"/>
<!-- Insert rel as last node -->
<xsl:attribute name="rel">noopener noreferrer</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a/@href|a/@target|a/@rel">
<!--
Allowed attribute on anchor
-->
<xsl:attribute name="{name()}">
<xsl:value-of select="."></xsl:value-of>
</xsl:attribute>
</xsl:template>
诺佩纳·诺弗勒
您还可以通过调用应用模板来指定属性序列,每次选择的顺序都是您想要的
<xsl:template match="a">
<xsl:copy>
<xsl:if test="starts-with(./@href,'http')">
<xsl:apply-templates select="./@id"/>
<xsl:apply-templates select="./@href"/>
<xsl:apply-templates select="./@target"/>
<!-- Insert rel as last node -->
<xsl:attribute name="rel">noopener noreferrer</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
诺佩纳·诺弗勒
感谢各位的回复。我不是很清楚。我实际上不需要按属性名称对属性进行排序,而是自己指定一个顺序。假设一个文档需要按顺序1、2、3、4显示它们。另一个按顺序2,3。另一个假设是3,1,2,4。我想知道我是否能以某种方式存储属性名的特定序列。。然后,只需对它们进行迭代。基本上,在显示一系列属性值时,要有简洁且非常灵活的内容。希望这有意义?
<xsl:template match="a">
<xsl:copy>
<xsl:if test="starts-with(./@href,'http')">
<xsl:apply-templates select="./@id"/>
<xsl:apply-templates select="./@href"/>
<xsl:apply-templates select="./@target"/>
<!-- Insert rel as last node -->
<xsl:attribute name="rel">noopener noreferrer</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>