我想编写一个XSLT样式表,它通过一些映射规则映射元素名称。为了让样式表可以为经验较少的用户自定义,我想在样式表中单独存储地图:
<mr:mapping-rules>
<field src="field1" dest="field1337" />
<field src="field2" dest="field2" />
<field src="field3" dest="field3" />
</mr:mapping-rules>
以下是一些示例输入数据:
<Record>
<field1>123</field1>
<field2>asd</field2>
<field3>456</field3>
</Record>
预期结果是:
<Record>
<field1337>123</field1337>
<field2>asd</field2>
<field3>456</field3>
</Record>
如果有人能给我一个暗示模板必须是什么样子的话会很好。
答案 0 :(得分:1)
根据我的评论,这是一个建议。我写了一个样式表,采用
形式的映射文件<mr:mapping-rules xmlns:mr="http://example.com/mr">
<context pattern="Record">
<field src="field1" dest="field1337" />
</context>
</mr:mapping-rules>
以
的形式生成样式表<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Record/field1">
<xsl:element name="field1337">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
创建上述样式表作为其输出的样式表是
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mr="http://example.com/mr"
xmlns:oxsl="http://example.com/xsl"
exclude-result-prefixes="oxsl mr">
<xsl:namespace-alias stylesheet-prefix="oxsl" result-prefix="xsl"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<oxsl:stylesheet version="1.0">
<oxsl:template match="@* | node()">
<oxsl:copy>
<oxsl:apply-templates select="@* | node()"/>
</oxsl:copy>
</oxsl:template>
<xsl:apply-templates/>
</oxsl:stylesheet>
</xsl:template>
<xsl:template match="mr:mapping-rules/context/field">
<oxsl:template match="{../@pattern}/{@src}">
<oxsl:element name="{@dest}">
<oxsl:apply-templates select="@* | node()"/>
</oxsl:element>
</oxsl:template>
</xsl:template>
</xsl:stylesheet>
然后,您可以在
之类的输入上运行生成的样式表<Root>
<Record-List>
<Record>
<field1>foo</field1>
<field2>bar</field2>
<field3>baz</field3>
</Record>
</Record-List>
</Root>
并输出
<Root>
<Record-List>
<Record>
<field1337>foo</field1337>
<field2>bar</field2>
<field3>baz</field3>
</Record>
</Record-List>
</Root>
当然,映射文件可以根据您的需要进行调整,我主要尝试显示一个样本,从映射文件生成第二个样式表,然后应用于输入样本。
答案 1 :(得分:1)
Martin的解决方案很好,因为这种方法非常强大且可扩展,但也可以更直接地解决问题:
<xsl:key name="mappings" match="mr:mapping-rules/field" use="@src"/>
<xsl:template match="*">
<xsl:element name="{(key('mappings', name())/@dest, name())[1]}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
<xsl:element>
</xsl:template>