如何根据元素属性的映射表重命名元素?
我们非常感谢任何建议。 也许是XSLT 2.0模板并修改映射表以获得更好的解决方案?
非常感谢提前 托马斯
原始XML:
<transaction>
<records type="1" >
<record type="1" >
<field number="1" >
<item>223</item>
</field>
<field number="2" >
<item>456</item>
</field>
</record>
</records>
<records type="14" >
<record type="14" >
<field number="1" >
<item>777</item>
</field>
<field number="2" >
<item>678</item>
</field>
</record>
<record type="14" >
<field number="1" >
<item>555</item>
</field>
</record>
</records>
</transaction>
映射表:
<xsl:stylesheet>
<mapping type="1" from="record" to="first-record">
<map number="1" from="field" to="great-field"/>
<map number="2" from="field" to="good-field"/>
</mapping>
<mapping type="14" from="record" to="real-record">
<map number="1" from="field" to="my-field"/>
<map number="2" from="field" to="other-field"/>
</mapping>
</xsl:stylesheet>
转型后的结果:
<transaction>
<records type="1" >
<first-record type="1" >
<great-field number="1" >
<item >223</item>
</great-field>
<good-field number="2" >
<item >456</item>
</good-field>
</first-record>
</records>
<records type="14" >
<real-record type="14" >
<my-field number="1" >
<item >777</item>
</my-field>
<other-field number="2" >
<item >678</item>
</other-field>
</real-record>
<real-record type="14" >
<my-field number="1" >
<item >555</item>
</my-field>
</real-record>
</records>
</transaction>
答案 0 :(得分:1)
这是一个XSLT 3.0样式表(可执行Saxon 9.8任何版本或Altova XMLSpy / Raptor 2017或2018),它将映射转换为XSLT 3.0样式表,然后使用XPath 3.1中的transform
函数执行它:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias"
exclude-result-prefixes="xs math axsl"
version="3.0">
<xsl:param name="mapping">
<mapping type="1" from="record" to="first-record">
<map number="1" from="field" to="great-field"/>
<map number="2" from="field" to="good-field"/>
</mapping>
<mapping type="14" from="record" to="real-record">
<map number="1" from="field" to="my-field"/>
<map number="2" from="field" to="other-field"/>
</mapping>
</xsl:param>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:variable name="stylesheet">
<axsl:stylesheet version="3.0">
<axsl:mode name="transform" on-no-match="shallow-copy"/>
<xsl:apply-templates select="$mapping/mapping" mode="xslt-modes"/>
<xsl:apply-templates select="$mapping/mapping" mode="xslt-code"/>
</axsl:stylesheet>
</xsl:variable>
<xsl:template match="mapping" mode="xslt-modes">
<axsl:mode name="transform-{position()}" on-no-match="shallow-copy"/>
</xsl:template>
<xsl:template match="mapping" mode="xslt-code">
<axsl:template match="{@from}[@type = '{@type}']" mode="transform">
<axsl:element name="{@to}">
<axsl:apply-templates select="@* | node()" mode="transform-{position()}"/>
</axsl:element>
</axsl:template>
<xsl:apply-templates mode="xslt-code">
<xsl:with-param name="pos" select="position()"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="map" mode="xslt-code">
<xsl:param name="pos"/>
<axsl:template match="{@from}[@number = '{@number}']" mode="transform-{$pos}">
<axsl:element name="{@to}">
<axsl:apply-templates select="@* | node()" mode="#current"/>
</axsl:element>
</axsl:template>
</xsl:template>
<xsl:template match="/">
<xsl:message select="$stylesheet"></xsl:message>
<xsl:sequence select="transform(map { 'source-node' : ., 'stylesheet-node' : $stylesheet , 'initial-mode' : xs:QName('transform') })?output"/>
</xsl:template>
</xsl:stylesheet>
删除或注释<xsl:message select="$stylesheet"></xsl:message>
,只显示生成的样式表代码。
当然,将映射转换为XSLT样式表的方法也可以与XSLT 2.0一起使用,但是您需要从XSLT外部运行创建的样式表,例如: Java或C#或在编辑器中手动完成。