这个问题实际上有些不同。请参阅@ Tomalak的回答以了解OP真正想要的内容。 :(
有没有办法在一个数组中的for-each循环期间存储变量/ param,并在另一个模板中使用它,即<xsl:template match="Foundation.Core.Classifier.feature">
。
应存储for-each期间出现的所有classname
值。你会如何在XSLT中实现它?这是我目前的代码。
<xsl:for-each select="Foundation.Core.Class">
<xsl:for-each select="Foundation.Core.ModelElement.name">
<xsl:param name="classname">
<xsl:value-of select="Foundation.Core.ModelElement.name"/>
</xsl:param>
</xsl:for-each>
<xsl:apply-templates select="Foundation.Core.Classifier.feature" />
</xsl:for-each>
以下是应使用classname
参数的模板。
<xsl:template match="Foundation.Core.Classifier.feature">
<xsl:for-each select="Foundation.Core.Attribute">
<owl:DatatypeProperty rdf:ID="{Foundation.Core.ModelElement.name}">
<rdfs:domain rdf:resource="$classname" />
</owl:DatatypeProperty>
</xsl:for-each>
</xsl:template>
找到
答案 0 :(得分:5)
不,不可能在for-each循环中存储变量并在以后使用它。
这是因为变量在XSLT中是一次写入的(一旦设置它们是不可变的)并且它们在其父元素中严格限定范围。一旦处理离开for-each循环,变量就会消失。
XSLT不能作为命令式编程语言,但这就是你在这里尝试的东西。 98%的情况下你不需要<xsl:for-each>
,不应该使用它,因为它会阻碍你对XSLT如何工作的看法。要改进你的XSLT代码,摆脱你拥有的所有<xsl:for-each>
循环(所有这些,我的意思是)并使用模板代替:
<xsl:template match="Foundation.Core.Class">
<xsl:apply-templates select="
Foundation.Core.Classifier.feature/Foundation.Core.Attribute
" />
</xsl:template>
<xsl:template match="Foundation.Core.Attribute">
<owl:DatatypeProperty rdf:ID="{Foundation.Core.ModelElement.name}">
<rdfs:domain rdf:resource="{
ancestor::Foundation.Core.Class[1]/Foundation.Core.ModelElement.name[1]
}" />
</owl:DatatypeProperty>
</xsl:template>
(我不确定以上是否是你真正想要的,你的问题很模糊。)
注意使用XPath ancestor
轴来引用层次结构中较高的元素(您似乎想要父类的<Foundation.Core.ModelElement.name>
。)
PS:由于结构化元素名称,您的XML非常臃肿且冗余。结构应该来自......井...... 结构,而不是像<Foundation.Core.Classifier.feature>
这样的元素。不过,我不确定你能不能做些什么。
增加:
要解决您的xmi.id
/ xmi.idref
问题,最好的方法是使用XSL密钥:
<!-- this indexes all elements by their @xmi.id attribute -->
<xsl:key name="kElementByIdref" match="*[@xmi.id]" use="@xmi.id" />
<!-- now you can do this -->
<xsl:template match="Foundation.Core.DataType">
<dataTypeName>
<!-- pull out the corresponding element from the key, output its value -->
<xsl:value-of select="key('kElementByIdref', @xmi.idref)" />
</dataTypeName>
</xsl:template>
为了更好地了解密钥在内部的工作方式,您可以阅读this answer I gave earlier。请不要过多地回答这个问题,只要阅读我的答案的下半部分,我就用JavaScript解释了密钥。
答案 1 :(得分:-1)
好的,我现在明白为什么并不总是需要for-each
。请考虑以下代码。
<Foundation.Core.DataType xmi.id="UID71848B1D-2741-447E-BD3F-BD606B7FD29E">
<Foundation.Core.ModelElement.name>int</Foundation.Core.ModelElement.name>
</Foundation.Core.DataType>
标识为UID71848B1D-2741-447E-BD3F-BD606B7FD29E
其他地方我有以下内容。
<Foundation.Core.StructuralFeature.type>
<Foundation.Core.DataType xmi.idref="UID71848B1D-2741-447E-BD3F-BD606B7FD29E"/>
</Foundation.Core.StructuralFeature.type>
如您所见,两个代码都具有相同的ID。现在我想输出“int”,每次这个ID出现在文档的某个地方。因此idref="UID71848B1D-2741-447E-BD3F-BD606B7FD29"
基本上应由int
替换,Foundation.Core.ModelElement.name
可以从{{1}}元素轻松派生。
以上是我想将其存储在变量中的主要原因。我不知道如何使用XSLT来解决这个问题。如果有人可以详细说明这一点,我希望存在某种解决这类问题的模式,因为我经常需要它。什么是好方法?
我知道这可能有点偏离主题,但我还是愿意在这个帖子中问它,因为这个问题非常接近它。