这是一个独立的选项,不需要任何外部 XML 文件。
当这个 XSLT:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
...针对提供的 XML 应用:
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
...产生了想要的结果:
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
解释:
或者,这里有一个不同的 XSLT 1.0 解决方案。如果出现以下情况,它可能会更有用:
document('')
由于某种原因,在您的环境中不可用。
或者
- 在您的 XSLT 中使用伪字典似乎有点笨拙(您愿意做一个小假设)。
当这个 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
...应用于相同的输入 XML,再次产生所需的结果:
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
解释:
请注意在 XSLT 顶部定义的变量:
<xsl:variable name="vStartingChar" select="'F'" />
这提供了一种方便的机制来更改新属性的起始字符。如前所述,如果继续使用相同的模式(即,附加属性将遵循相同的方案 - F4
、F5
等),则此解决方案的着色效果更好,因为它不需要您更新元素的“数组”。