2014-10-20 2 views
0

Я только начал работать над XSLT. Мой ввод и ожидаемый результат следующие, и XSLT также приведен ниже.xslt 2.0 изменить имя узла и обертывать узлы из tokenize

У меня есть следующий входной 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 это работает, но когда я пытался whit FONDOS, я получал XML-формат формата XML.

ответ

0

Я думаю, что вы просто хотите, чтобы сгруппировать элементы, такие как 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> 

Таким образом, с Saxon 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> 
+0

Спасибо большое, я попробовал и работает нормально, я меняю «match» на «* [name() = tokenize ($ elementsToWrap, '\ |')]", потому что я могу получить в качестве параметра имя узлов, которые будут сгруппированы , – user4160104

Смежные вопросы