2016-11-18 98 views
0

這可能是不可能的,但能跟大家可能有一個答案, IM試着將這個XML分割分裂XML元素成許多

<CTP> 
    <name>ABSA bank</name> 
    <BAs.BA>bank|sector|issuer</BAs.BA> 
</CTP> 

,並把它轉換爲這種形式:

<CTP> 
    <name>ABSA bank</name> 
    <BAs> 
     <BA>bank</BA> 
     <BA>sector</BA> 
     <BA>issuer</BA> 
    </BAs> 
</CTP> 

我能做到這一點使用此代碼

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" version="1.0" extension-element-prefixes="str"> 
    <xsl:template name="str:tokenize"> 
    <xsl:param name="string" select="''" /> 
    <xsl:param name="delimiters" select="'&#x9;&#xA;'" /> 
    <xsl:choose> 
     <xsl:when test="not($string) or (string-length($string)=0)" /> 
     <xsl:when test="not($delimiters) or (string-length($delimiters)=0)"> 
     <xsl:call-template name="str:_tokenize-characters"> 
      <xsl:with-param name="string" select="$string" /> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:call-template name="str:_tokenize-delimiters"> 
      <xsl:with-param name="string" select="$string" /> 
      <xsl:with-param name="delimiters" select="$delimiters" /> 
     </xsl:call-template> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
    <xsl:template name="str:_tokenize-characters"> 
    <xsl:param name="string" /> 
    <xsl:if test="$string"> 
     <BA> 
     <xsl:value-of select="substring($string, 1, 1)" /> 
     </BA> 
     <xsl:call-template name="str:_tokenize-characters"> 
     <xsl:with-param name="string" select="substring($string, 2)" /> 
     </xsl:call-template> 
    </xsl:if> 
    </xsl:template> 
    <xsl:template name="str:_tokenize-delimiters"> 
    <xsl:param name="string" /> 
    <xsl:param name="delimiters" /> 
    <xsl:variable name="delimiter" select="substring($delimiters, 1, 1)" /> 
    <xsl:choose> 
     <xsl:when test="string-length($delimiter)=0"> 
     <BA> 
      <xsl:value-of select="$string" /> 
     </BA> 
     </xsl:when> 
     <xsl:when test="contains($string, $delimiter)"> 
     <xsl:choose> 
      <xsl:when test="not(starts-with($string, $delimiter))"> 
      <xsl:call-template name="str:_tokenize-delimiters"> 
       <xsl:with-param name="string" select="substring-before($string, $delimiter)" /> 
       <xsl:with-param name="delimiters" select="substring($delimiters, 2)" /> 
      </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
      <BA /> 
      </xsl:otherwise> 
     </xsl:choose> 
     <xsl:call-template name="str:_tokenize-delimiters"> 
      <xsl:with-param name="string" select="substring-after($string, $delimiter)" /> 
      <xsl:with-param name="delimiters" select="$delimiters" /> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:call-template name="str:_tokenize-delimiters"> 
      <xsl:with-param name="string" select="$string" /> 
      <xsl:with-param name="delimiters" select="substring($delimiters, 2)" /> 
     </xsl:call-template> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
    <xsl:template match="/"> 
    <xsl:variable name="v1"> 
     <xsl:value-of select="CTP/BAs.BA" /> 
    </xsl:variable> 
    <BAs> 
     <xsl:call-template name="str:tokenize"> 
     <xsl:with-param name="string" select="$v1" /> 
     <xsl:with-param name="delimiters" select="'#'" /> 
     </xsl:call-template> 
    </BAs> 
    </xsl:template> 
</xsl:stylesheet> 

但主要的挑戰是如何使動態的,換句話說,我希望「的BA」 和「BA」節點,以動態寫入的情況下,我還有其他的XML,如:

<CTP> 
    <name>ABSA bank</name> 
    <FAs.FA>dep|sec|issue</BAs.BA> 
</CTP> 

我希望它看起來像這樣:

<CTP> 
    <name>ABSA bank</name> 
    <FAs> 
     <FA>bank</BA> 
     <FA>sector</BA> 
     <FA>issuer</BA> 
    </FAs> 
</CTP> 
+0

的問題是不明確的。元素名稱中總會有兩個標記,還是可以有更多? –

+0

作爲第一步,虐待它與2令牌,如果它的作品,我們會嘗試2+標記,但首先我的目標是實現2令牌的挑戰。 @ michael.hor257k –

+0

@ michael.hor257k,你能否檢查第二步,你認爲這是可行的嗎? –

回答

0

試試這樣說:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[contains(name(), '.')]" name="nest"> 
    <xsl:param name="name" select="name()"/> 
    <xsl:param name="delimiter" select="'.'"/> 
    <xsl:choose> 
     <xsl:when test="contains($name, $delimiter)"> 
      <xsl:element name="{substring-before($name, $delimiter)}" > 
       <!-- recursive call --> 
       <xsl:call-template name="nest"> 
        <xsl:with-param name="name" select="substring-after($name, $delimiter)"/> 
       </xsl:call-template> 
      </xsl:element> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:call-template name="tokenize"> 
       <xsl:with-param name="name" select="$name"/> 
       <xsl:with-param name="text" select="."/> 
      </xsl:call-template> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="tokenize"> 
    <xsl:param name="name"/> 
    <xsl:param name="text"/> 
    <xsl:param name="delimiter" select="'|'"/> 
    <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" /> 
    <xsl:if test="$token"> 
     <xsl:element name="{$name}" > 
      <xsl:value-of select="$token"/> 
     </xsl:element> 
    </xsl:if> 
    <xsl:if test="contains($text, $delimiter)"> 
     <!-- recursive call --> 
     <xsl:call-template name="tokenize"> 
      <xsl:with-param name="name" select="$name"/> 
      <xsl:with-param name="text" select="substring-after($text, $delimiter)"/> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

施加到下面的測試輸入:

XML

<CTP> 
    <name>ABSA bank</name> 
    <BAs.BA>bank|sector|issuer</BAs.BA> 
    <FAs.FA.F>dep|sec|issue</FAs.FA.F> 
</CTP> 

結果將是:

<?xml version="1.0" encoding="UTF-8"?> 
<CTP> 
    <name>ABSA bank</name> 
    <BAs> 
     <BA>bank</BA> 
     <BA>sector</BA> 
     <BA>issuer</BA> 
    </BAs> 
    <FAs> 
     <FA> 
     <F>dep</F> 
     <F>sec</F> 
     <F>issue</F> 
     </FA> 
    </FAs> 
</CTP> 
+0

你是什麼人超音速,waw。謝謝你,先生。 –