xslt 2.0更改节点名称和包装来自标记大小的节点
问题描述:
我刚开始使用XSLT。我的输入和预期输出如下,XSLT也在下面给出。xslt 2.0更改节点名称和包装来自标记大小的节点
我有一个输入的xml:
<servicio>
<control>
<codSer>00013</codSer>
<idMen>12378658936578</idMen>
<codErr>000</codErr>
<numId>000xxxxxxxx</numId>
</control>
<cuentas>
<tipPro>3</tipPro>
<numCta>000000006</numCta>
<tipCta>A</tipCta>
<desCta>Cuenta I</desCta>
<saldo>001513003135</saldo>
</cuentas>
<cuentas>
<tipPro>1</tipPro>
<numCta>000000005</numCta>
<tipCta>A</tipCta>
<desCta>Cuenta I</desCta>
<saldo>007573144537</saldo>
<signo>Pos</signo>
</cuentas>
<fondos>
<tipPro>4</tipPro>
<numCta>000000007</numCta>
<tipCta>A</tipCta>
<desCta>Fondo I</desCta>
<saldo>001513003135</saldo>
</fondos>
<fondos>
<tipPro>4</tipPro>
<numCta>000000008</numCta>
<tipCta>A</tipCta>
<desCta>Fondo I</desCta>
<saldo>007573144537</saldo>
</fondos>
</servicio>
,我需要应用一个XSL来获得(输出):
<servicio>
<control>
<codSer>00013</codSer>
<idMen>12378658936578</idMen>
<codErr>000</codErr>
<numId>000xxxxxxxx</numId>
</control>
<cuentas>
<cuenta>
<tipPro>3</tipPro>
<numCta>000000006</numCta>
<tipCta>A</tipCta>
<desCta>Cuenta I</desCta>
<saldo>001513003135</saldo>
</cuenta>
<cuenta>
<tipPro>1</tipPro>
<numCta>000000005</numCta>
<tipCta>A</tipCta>
<desCta>Cuenta I</desCta>
<saldo>007573144537</saldo>
<signo>Pos</signo>
</cuenta>
</cuentas>
<fondos>
<fondo>
<tipPro>4</tipPro>
<numCta>000000007</numCta>
<tipCta>A</tipCta>
<desCta>Fondo I</desCta>
<saldo>001513003135</saldo>
</fondo>
<fondo>
<tipPro>4</tipPro>
<numCta>000000008</numCta>
<tipCta>A</tipCta>
<desCta>Fondo I</desCta>
<saldo>007573144537</saldo>
</fondo>
</fondos>
</servicio>
我尝试和没有工作的XSL是:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:output indent="yes" />
<xsl:param name="elementInfo" select="cuentas,cuentas,cuenta;fondos,fondos,fondo"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="node()[name() = name(/*)]">
<xsl:variable name="inputNode" select="." />
<xsl:for-each select="tokenize($elementInfo, ';')">
<xsl:variable name="tokenizedNodeNames" select="tokenize(.,',')" />
<xsl:for-each select="$inputNode">
<xsl:call-template name="wrapping">
<xsl:with-param name="wrapperElementName" select="$tokenizedNodeNames[1]" />
<xsl:with-param name="oldElementName" select="$tokenizedNodeNames[2]" />
<xsl:with-param name="newElementName" select="$tokenizedNodeNames[3]" />
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="wrapping">
<xsl:param name="wrapperElementName" />
<xsl:param name="oldElementName" />
<xsl:param name="newElementName" />
<xsl:copy>
<xsl:apply-templates select="node()[not(name() = $oldElementName)]" />
<xsl:element name="{$wrapperElementName}">
<xsl:for-each select="node()[name() = $oldElementName]">
<xsl:element name="{$newElementName}">
<xsl:copy-of select="@*|node()" />
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:copy>
</xsl:template>
当我有一个输入XM L whit仅适用于CUENTAS,但是当我尝试使用FONDOS时,我使用的是格式化XML。
答
我觉得你只是想喜欢cuentas
和fondos
族元素通过node-name()
:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each-group select="*" group-by="node-name(.)">
<xsl:apply-templates select="." mode="wrap"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="wrap">
<xsl:apply-templates select="current-group()"/>
</xsl:template>
<xsl:template match="cuentas | fondos" mode="wrap">
<xsl:copy>
<xsl:apply-templates select="current-group()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="cuentas | fondos">
<xsl:element name="{substring(local-name(), 1, string-length(local-name()) - 1)}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这样一来,与撒克逊9.5,我得到的结果
<servicio>
<control>
<codSer>00013</codSer>
<idMen>12378658936578</idMen>
<codErr>000</codErr>
<numId>000xxxxxxxx</numId>
</control>
<cuentas>
<cuenta>
<tipPro>3</tipPro>
<numCta>000000006</numCta>
<tipCta>A</tipCta>
<desCta>Cuenta I</desCta>
<saldo>001513003135</saldo>
</cuenta>
<cuenta>
<tipPro>1</tipPro>
<numCta>000000005</numCta>
<tipCta>A</tipCta>
<desCta>Cuenta I</desCta>
<saldo>007573144537</saldo>
<signo>Pos</signo>
</cuenta>
</cuentas>
<fondos>
<fondo>
<tipPro>4</tipPro>
<numCta>000000007</numCta>
<tipCta>A</tipCta>
<desCta>Fondo I</desCta>
<saldo>001513003135</saldo>
</fondo>
<fondo>
<tipPro>4</tipPro>
<numCta>000000008</numCta>
<tipCta>A</tipCta>
<desCta>Fondo I</desCta>
<saldo>007573144537</saldo>
</fondo>
</fondos>
</servicio>
非常感谢你,我尝试它并且工作正常,我只将“匹配”更改为“* [name()= tokenize($ elementsToWrap,'\'')]”,因为我可以接收作为参数的将被分组的节点的名称。 – user4160104 2014-10-24 15:40:39