全局变量表示,对于各种元素,需要处理哪些属性。
<xsl:variable name="attributes.rtf">
<element name="measure">
<att>type</att>
<att>quantity</att>
<att>unit</att>
</element>
<element name="milestone">
<att>n</att>
</element>
<element name="lb">
<att>ed</att>
<att>type</att>
<att>subtype</att>
<att>n</att>
</element>
</xsl:variable>
<xsl:variable name="attributes" select="exslt:node-set($attributes.rtf)" /> <!-- This is XSLT 1.0 -->
当上下文是一个元素时,我需要一个for-each,它将遍历那种元素的属性。我没有看到如何在一个XPath表达式中执行此操作。现在我有这两个:
<xsl:variable name="temp" select="." /> <!-- For, say, a <measure> element, -->
<xsl:for-each select="$attributes/element[@name=name($temp)]/att"> <!-- loop through the names "type", "quantity", and "unit" -->
<xsl:for-each select="$temp/@*[name()=current()]"> <!-- If an attribute of that name exists in the current <measure> element -->
<!-- (now stored as $temp), then process that attribute. -->
</xsl:for-each>
</xsl:for-each>
有没有办法在一个表达式中执行此操作,而无需创建$ temp。
但是,我还需要一个外部测试条件,指示上下文元素是否具有任何列出的属性。对于那个测试,我想要一个表达式。
(属性的处理确实需要排序,所以可能需要两个循环。但是顺序与测试条件无关。所以也许只需要用一个表达式完成。)
答案 0 :(得分:2)
<强>予。 “简单”问题:
When the context is an element, I need a for-each that will loop through attributes for that kind of element.
不需要xsl-for-each
。
I don't see how to do this in one XPath expression.
只需使用:
<xsl:apply-templates select=
"@*[name()=$attributes/element[@name=name(current())]/att]"/>
<强>解释强>:
正确使用 current()
功能。
<强> II。 “复杂”问题:
Processing of the attributes does need to be ordered, so maybe that requires the two loops
以下是一个完整示例,显示没有其他嵌套 <xsl:apply-templates>
是必要的,以按{{1}中指定的顺序生成属性} 强>
$attributes
在以下XML文档中应用此转换时(没有提供!!!):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="attributes.rtf">
<element name="measure">
<att>type</att>
<att>quantity</att>
<att>unit</att>
</element>
<element name="milestone">
<att>n</att>
</element>
<element name="lb">
<att>ed</att>
<att>type</att>
<att>subtype</att>
<att>n</att>
</element>
</xsl:variable>
<xsl:variable name="attributes" select="exslt:node-set($attributes.rtf)" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="t/*">
<xsl:copy>
<xsl:apply-templates select="$attributes/element[@name=name(current())]/att">
<xsl:with-param name="pCurrent" select="current()"/>
</xsl:apply-templates>
<xsl:apply-templates select=
"@*[not(name() = $attributes/element[@name=name(current())]/att)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="att">
<xsl:param name="pCurrent" select="/.."/>
<xsl:if test="$pCurrent[@*[name()=current()]]">
<xsl:attribute name="{.}">
<xsl:value-of select="concat(.,'-',.)"/>
</xsl:attribute>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
产生了想要的正确结果:
<t>
<lb type="normal" ed="uni" n="3"
subtype="initial" other="yes"/>
<milestone n="2" other="yes"/>
<measure quantity="3" unit="cm"
type="length" other="yes"/>
</t>