如何根据元素的属性根据映射表重命名元素?
任何建议将不胜感激.
也许是一个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>
这是一个XSLT 3.0样式表(可执行Saxon 9.8任何版本或Altova XMLSpy / Raptor 2017或2018),它将映射转换为XSLT 3.0样式表,然后使用XPath 3.1中的转换函数执行它:
<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#或在编辑器中手动编写.