问题1。
对于您遇到的第一个问题,您可以使用密钥:
<xsl:key name="variable-key" match="//variable" use="@name" />
该键将使用它们的名称索引文档中的所有变量元素。所以现在,我们可以使用以下 XPath 表达式访问这些元素中的任何一个:
key('variable-key', 'X')
当您有很多可变元素时,使用这种方法是有效的。
注意:如果每个变量都有自己的范围(即您有在文档的不同部分不可见的局部变量),则此方法无效。在这种情况下,应该修改这种方法。
问题 2。
对于映射属性,您可以使用如下模板:
<xsl:template match="@baseType[. = 'int']">
<xsl:attribute name="baseType">
<xsl:value-of select="'Long'" />
</xsl:attribute>
</xsl:template>
这个转换的意思是:每次我们匹配一个baseType属性和int值,它都必须被一个Long值替换。
对于文档中的每个 @baseType 属性,都将进行此转换。
使用所描述的策略,解决方案可能是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<!-- Index all variable elements in the document by name -->
<xsl:key name="variable-key"
match="//variable"
use="@name" />
<!-- Just for demo -->
<xsl:template match="text()" />
<!-- Identity template: copy attributes by default -->
<xsl:template match="@*">
<xsl:copy>
<xsl:value-of select="." />
</xsl:copy>
</xsl:template>
<!-- Match the structure type -->
<xsl:template match="type[@baseType='structure']">
<Item>
<xsl:apply-templates select="*|@*" />
</Item>
</xsl:template>
<!-- Match the variable instance -->
<xsl:template match="variableInstance">
<Field>
<!-- Use the key to find the variable with the current name -->
<xsl:apply-templates select="@*|key('variable-key', @name)/@baseType" />
</Field>
</xsl:template>
<!-- Ignore attributes with baseType = 'structure' -->
<xsl:template match="@baseType[. = 'structure']" />
<!-- Change all baseType attributes with long values to an attribute
with the same name but with an int value -->
<xsl:template match="@baseType[. = 'int']">
<xsl:attribute name="baseType">
<xsl:value-of select="'Long'" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
该代码将转换以下 XML 文档:
<!-- The code element is present just for demo -->
<code>
<variable baseType="int" name="X" />
<type baseType="structure" name="Y">
<variableInstance name="X" />
</type>
</code>
进入
<Item name="Y">
<Field baseType="Long" name="X"/>
</Item>