XSLT,使用基于属性值的映射 table 重命名元素
XSLT, Renaming Elements using mapping table based on Attribute's value
如何根据基于元素属性的映射 table 重命名元素?
如有任何建议,我们将不胜感激。
也许 XSLT 2.0 模板和修改映射 table 以获得更好的解决方案?
非常感谢
托马斯
原文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>
映射table:
<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 样式表,然后使用 transform
函数执行它来自 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# 或在您的编辑器中手动编写。
如何根据基于元素属性的映射 table 重命名元素?
如有任何建议,我们将不胜感激。 也许 XSLT 2.0 模板和修改映射 table 以获得更好的解决方案?
非常感谢 托马斯
原文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>
映射table:
<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 样式表,然后使用 transform
函数执行它来自 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# 或在您的编辑器中手动编写。